/* =========================================================
   THE ALMANAC — a personal site set like a printed one
   ---------------------------------------------------------
   The organising idea is a printer's almanac: numbered
   sections, hairline rules instead of boxes and shadows,
   figures set in mono, and voice set in serif. Nothing is
   separated by a drop shadow that could be separated by a
   rule and some air.

   Three voices, strictly kept:
     display — Fraunces, for anything that is a *title*
     read    — Newsreader, for anything that is *read*
     data    — IBM Plex Mono, for anything that is a *fact*
               (dates, periods, counts, ranks, labels)

   Devanagari has no glyphs in the first three families, so
   the browser falls through per character to Tiro — which
   means Hindi book titles get properly set with no extra
   markup anywhere in the HTML.

   Fonts are linked from each page's <head> rather than
   @import-ed here; an @import inside CSS serialises the two
   requests and delays first paint.
   ========================================================= */

/* ---------------------------------------------------------
   1. Tokens
   --------------------------------------------------------- */
:root {
    --font-display: 'Fraunces', 'Tiro Devanagari Hindi', Georgia, serif;
    --font-read: 'Newsreader', 'Tiro Devanagari Hindi', Georgia, serif;
    --font-data: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    /* Type scale, ~1.26 ratio, fluid at the top end only —
       body text should not move when the window does. */
    --t-2xs: 0.6875rem;
    --t-xs: 0.75rem;
    --t-sm: 0.8125rem;
    --t-base: 1rem;
    --t-md: 1.125rem;
    --t-lg: 1.375rem;
    --t-xl: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
    --t-2xl: clamp(2rem, 1.5rem + 2.2vw, 3rem);
    --t-3xl: clamp(2.75rem, 1.6rem + 5vw, 5.25rem);

    /* Rhythm */
    --gutter: clamp(1.25rem, 4vw, 3rem);
    --wrap: 74rem;
    --measure: 41rem;
    --section-gap: clamp(4.5rem, 9vw, 8rem);

    /* Paper. The neutrals carry a warm bias so they read as
       stock rather than as an unconsidered mid-grey. */
    --paper: #f6f2e9;
    --paper-2: #fbf8f2;
    --paper-3: #efe9dc;
    --ink: #16130d;
    --ink-2: #5c5648;
    /* --ink-3 carries most of the small mono labels, so it has to clear
       4.5:1 on --paper rather than merely look muted. 5.10:1 here. */
    --ink-3: #6c665a;
    --rule: #ddd5c4;
    --rule-2: #c9bfa9;
    --accent: #a8461c;
    --accent-2: #c2661f;
    /* Gilt for the shelf marks, which sit on dark cloth. */
    --gold: #957015;
    /* Rating stars are small text on paper, so they need their own,
       darker gold — 4.89:1 rather than the gilt's 4.08:1. */
    --star: #866412;
    --board: #cdc2ab;

    --tint: rgba(168, 70, 28, 0.08);
    --lift: 0 18px 44px rgba(22, 19, 13, 0.16);
    --spine-shadow: 3px 5px 10px rgba(22, 19, 13, 0.14);

    /* Shelf geometry. The board line under each row is painted
       from these, so changing the height keeps the shelf true. */
    --spine-h: 264px;
    --shelf-row-gap: 40px;

    color-scheme: light;
}

/* Dark is a *press* dark: a deep warm charcoal, never blue-black,
   so the same paper metaphor survives the switch. Both the media
   query and the explicit attribute are defined, and the attribute
   wins in both directions so the toggle always beats the system. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) {
        --paper: #14120e;
        --paper-2: #1c1a15;
        --paper-3: #221f19;
        --ink: #ece5d6;
        --ink-2: #a09883;
        --ink-3: #878171;
        --rule: #2e2a22;
        --rule-2: #433d32;
        --accent: #e08a4f;
        --accent-2: #efa670;
        --gold: #c9a44a;
        --star: #d8b45c;
        --board: #3a352b;
        --tint: rgba(224, 138, 79, 0.12);
        --lift: 0 18px 44px rgba(0, 0, 0, 0.6);
        --spine-shadow: 3px 5px 12px rgba(0, 0, 0, 0.45);
        color-scheme: dark;
    }
}

:root[data-theme='dark'] {
    --paper: #14120e;
    --paper-2: #1c1a15;
    --paper-3: #221f19;
    --ink: #ece5d6;
    --ink-2: #a09883;
    --ink-3: #878171;
    --rule: #2e2a22;
    --rule-2: #433d32;
    --accent: #e08a4f;
    --accent-2: #efa670;
    --gold: #c9a44a;
    --star: #d8b45c;
    --board: #3a352b;
    --tint: rgba(224, 138, 79, 0.12);
    --lift: 0 18px 44px rgba(0, 0, 0, 0.6);
    --spine-shadow: 3px 5px 12px rgba(0, 0, 0, 0.45);
    color-scheme: dark;
}

/* ---------------------------------------------------------
   2. Base
   --------------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    /* Anchors land below the sticky masthead rule. */
    scroll-padding-top: 5.5rem;
    -webkit-text-size-adjust: 100%;
}

body {
    background-color: var(--paper);
    color: var(--ink);
    font-family: var(--font-read);
    font-size: var(--t-md);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

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

/* The browser's own [hidden] rule is only `display: none` at UA
   specificity, so any component that sets its own `display` — the
   shelf is `flex`, a .btn is `inline-flex` — silently outranks it
   and the element stays on screen. This makes `hidden` mean hidden. */
[hidden] {
    display: none !important;
}

a {
    color: var(--accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.18em;
}

a:hover {
    color: var(--accent-2);
}

::selection {
    background: var(--tint);
    color: var(--ink);
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 2px;
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.015em;
    font-variation-settings: 'opsz' 48, 'SOFT' 0, 'WONK' 0;
    text-wrap: balance;
}

/* ---------------------------------------------------------
   3. Primitives
   --------------------------------------------------------- */
.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.wrap--narrow {
    max-width: calc(var(--measure) + var(--gutter) * 2);
}

.data {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

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

.skip-link {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, -120%);
    z-index: 100;
    background: var(--ink);
    color: var(--paper);
    padding: 0.6rem 1.2rem;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    text-decoration: none;
    transition: transform 0.18s ease;
}

.skip-link:focus {
    transform: translate(-50%, 0);
    color: var(--paper);
}

/* Buttons —— outlined, never filled with a gradient. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.55em;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0.85em 1.4em;
    border: 1px solid var(--ink);
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.btn:hover {
    background: var(--ink);
    color: var(--paper);
}

.btn--solid {
    background: var(--ink);
    color: var(--paper);
}

.btn--solid:hover {
    background: var(--accent);
    border-color: var(--accent);
    /* Not #fff: in dark mode the accent lightens, and white-on-accent
       drops to 2.65:1. --paper flips with the theme and stays legible. */
    color: var(--paper);
}

.btn--quiet {
    border-color: var(--rule-2);
    color: var(--ink-2);
}

.btn--quiet:hover {
    border-color: var(--ink);
    background: transparent;
    color: var(--ink);
}

/* The recurring "→" link used to leave a section. */
.more-link {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5em;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--ink-2);
    border-bottom: 1px solid var(--rule-2);
    padding-bottom: 0.35em;
    transition: color 0.18s ease, border-color 0.18s ease;
}

.more-link:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.more-link span {
    transition: transform 0.18s ease;
}

.more-link:hover span {
    transform: translateX(3px);
}

/* ---------------------------------------------------------
   4. Masthead bar (site nav)
   --------------------------------------------------------- */
.topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--paper);
    background: color-mix(in srgb, var(--paper) 88%, transparent);
    backdrop-filter: saturate(140%) blur(12px);
    -webkit-backdrop-filter: saturate(140%) blur(12px);
    border-bottom: 1px solid var(--rule);
}

.topbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 4rem;
}

.wordmark {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    text-decoration: none;
    color: var(--ink);
}

.monogram {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    background: var(--ink);
    color: var(--paper);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
    transition: background-color 0.2s ease;
}

.wordmark:hover .monogram {
    background: var(--accent);
    color: #fff;
}

.wordmark-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
}

.topbar-nav {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2.4vw, 2rem);
    list-style: none;
}

.topbar-nav a {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--ink-2);
    padding-block: 0.3rem;
    border-bottom: 1px solid transparent;
    transition: color 0.18s ease, border-color 0.18s ease;
}

.topbar-nav a:hover {
    color: var(--ink);
}

.topbar-nav a[aria-current='page'] {
    color: var(--ink);
    border-color: var(--accent);
}

.topbar-tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.icon-btn {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.icon-btn:hover {
    border-color: var(--ink-3);
    color: var(--ink);
}

.icon-btn svg {
    width: 1rem;
    height: 1rem;
}

/* The theme button holds both glyphs and shows the one that
   describes what a click will *do*. */
.theme-btn .icon-moon { display: none; }
:root[data-theme='dark'] .theme-btn .icon-moon { display: block; }
:root[data-theme='dark'] .theme-btn .icon-sun { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) .theme-btn .icon-moon { display: block; }
    :root:not([data-theme='light']) .theme-btn .icon-sun { display: none; }
}

.menu-btn {
    display: none;
}

@media (max-width: 46rem) {
    .menu-btn {
        display: grid;
    }

    .topbar-nav {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: var(--paper);
        border-bottom: 1px solid var(--rule);
        padding: 0.5rem var(--gutter) 1.25rem;
        display: none;
    }

    .topbar-nav.is-open {
        display: flex;
    }

    .topbar-nav a {
        padding-block: 0.9rem;
        border-bottom: 1px solid var(--rule);
        font-size: var(--t-sm);
    }

    .topbar-nav li:last-child a {
        border-bottom: 0;
    }
}

/* ---------------------------------------------------------
   5. Section scaffolding
   ---------------------------------------------------------
   Every section opens with a rule, a number and a title, so
   the page reads as a numbered run of chapters.
   --------------------------------------------------------- */
.section {
    padding-block: var(--section-gap);
}

.section + .section {
    padding-top: 0;
}

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding-top: 1.1rem;
    border-top: 1px solid var(--ink);
    margin-bottom: clamp(2rem, 4vw, 3rem);
}

.section-title {
    display: flex;
    align-items: baseline;
    gap: 0.9rem;
    font-size: var(--t-xl);
}

.section-num {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.14em;
    color: var(--accent);
    font-weight: 500;
    transform: translateY(-0.15em);
}

.section-note {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.06em;
    color: var(--ink-3);
    max-width: 34ch;
    text-transform: none;
    line-height: 1.5;
}

.section-foot {
    margin-top: 2.5rem;
    display: flex;
    justify-content: flex-end;
}

/* Interior pages end on content rather than on a section, so they
   ask for the closing air themselves. */
.page-body {
    padding-bottom: clamp(3.5rem, 7vw, 6rem);
}

/* ---------------------------------------------------------
   6. Masthead / hero
   --------------------------------------------------------- */
.masthead {
    padding-top: clamp(3rem, 7vw, 6rem);
    /* No bottom padding: the figure strip's own rule closes the
       masthead, and the next section brings its own air. */
    padding-bottom: 0;
}

.masthead-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: end;
}

.masthead-eyebrow {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 1.75rem;
}

.masthead-eyebrow::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--rule);
}

.masthead h1 {
    font-size: var(--t-3xl);
    font-weight: 700;
    line-height: 0.94;
    letter-spacing: -0.035em;
    font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 1;
    margin-bottom: 1.5rem;
}

.masthead h1 .surname {
    display: block;
    color: var(--accent);
    font-style: italic;
    font-weight: 500;
}

.masthead-role {
    font-family: var(--font-read);
    font-size: clamp(1.1rem, 0.9rem + 0.6vw, 1.4rem);
    line-height: 1.45;
    color: var(--ink);
    max-width: 34ch;
    margin-bottom: 1.25rem;
}

.masthead-about {
    font-size: var(--t-base);
    color: var(--ink-2);
    max-width: 46ch;
    margin-bottom: 2.25rem;
}

.masthead-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* The portrait is mounted like a frontispiece plate: a paper
   mount, a hairline, and a caption set in mono beneath. */
.plate {
    margin: 0;
}

.plate-frame {
    background: var(--paper-2);
    border: 1px solid var(--rule);
    padding: 0.6rem;
}

.plate img {
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    object-position: center 20%;
    filter: saturate(0.92) contrast(1.02);
}

.plate figcaption {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 0.7rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* Figure strip — four facts, hairline-divided. */
.figures {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    border-top: 1px solid var(--ink);
    border-bottom: 1px solid var(--rule);
    margin-top: clamp(2.5rem, 5vw, 4rem);
}

.figure {
    padding: 1.4rem 1.25rem 1.5rem;
    border-left: 1px solid var(--rule);
}

.figure:first-child {
    border-left: 0;
    padding-left: 0;
}

.figure-value {
    display: block;
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.4rem);
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.02em;
    font-feature-settings: 'tnum' 1;
}

.figure-label {
    display: block;
    margin-top: 0.6rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
    line-height: 1.4;
}

/* ---------------------------------------------------------
   7. Work ledger
   --------------------------------------------------------- */
.ledger {
    list-style: none;
    border-top: 1px solid var(--rule);
}

.ledger-row {
    display: grid;
    grid-template-columns: 15rem minmax(0, 1fr);
    gap: 1.5rem 2.5rem;
    padding-block: clamp(1.6rem, 3vw, 2.25rem);
    border-bottom: 1px solid var(--rule);
    align-items: baseline;
}

.ledger-period {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.07em;
    color: var(--ink-3);
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-wrap: wrap;
}

.now-pill {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
    border: 1px solid currentColor;
    padding: 0.1em 0.5em;
}

.ledger-role {
    font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.7rem);
    font-weight: 600;
    letter-spacing: -0.02em;
}

.ledger-company {
    margin-top: 0.35rem;
    font-family: var(--font-read);
    font-size: var(--t-base);
    color: var(--ink-2);
}

.ledger-company strong {
    color: var(--ink);
    font-weight: 600;
}

.ledger-summary {
    margin-top: 0.75rem;
    color: var(--ink-2);
    font-size: var(--t-base);
    max-width: 52ch;
}

/* ---------------------------------------------------------
   8. Cards — writing, talks
   --------------------------------------------------------- */
.feature-post {
    display: block;
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--rule);
    background: var(--paper-2);
    padding: clamp(1.5rem, 3.5vw, 2.75rem);
    transition: border-color 0.2s ease, transform 0.2s ease;
}

.feature-post:hover {
    border-color: var(--ink-3);
    transform: translateY(-2px);
    color: inherit;
}

.post-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 1rem;
}

.post-meta .dot::before {
    content: '·';
    margin-inline: 0.1rem;
}

.feature-post h3 {
    font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.35rem);
    line-height: 1.08;
    letter-spacing: -0.025em;
    margin-bottom: 0.9rem;
    max-width: 24ch;
}

.feature-post:hover h3 {
    color: var(--accent);
}

/* :not() keeps this off .post-meta, which is also a <p> here and
   would otherwise lose its own smaller mono size to this rule. */
.feature-post p:not(.post-meta) {
    color: var(--ink-2);
    max-width: 58ch;
    font-size: var(--t-base);
}

.tag-row {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.tag {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
    border: 1px solid var(--rule-2);
    padding: 0.25em 0.65em;
}

/* Post index (blog listing) */
.post-index {
    list-style: none;
    border-top: 1px solid var(--ink);
}

.post-index li {
    border-bottom: 1px solid var(--rule);
}

.post-index a {
    display: grid;
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 0.75rem 2.5rem;
    padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
    text-decoration: none;
    color: inherit;
    transition: background-color 0.2s ease;
}

.post-index a:hover {
    background: var(--tint);
    color: inherit;
}

.post-index-date {
    font-family: var(--font-data);
    font-size: var(--t-sm);
    letter-spacing: 0.07em;
    color: var(--ink-3);
    padding-top: 0.35rem;
}

.post-index h2 {
    font-size: clamp(1.4rem, 1.1rem + 1.2vw, 2rem);
    line-height: 1.12;
    letter-spacing: -0.02em;
    max-width: 26ch;
}

.post-index a:hover h2 {
    color: var(--accent);
}

.post-index p:not(.post-index-date) {
    margin-top: 0.7rem;
    color: var(--ink-2);
    font-size: var(--t-base);
    max-width: 60ch;
}

/* Research — the venue and year sit in the left rail like a
   citation stamp, the title carries the weight. */
.paper-list {
    list-style: none;
    border-top: 1px solid var(--rule);
}

.paper-item {
    display: grid;
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 0.75rem 2.5rem;
    padding-block: clamp(1.75rem, 3.5vw, 2.5rem);
    border-bottom: 1px solid var(--rule);
}

.paper-stamp {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding-top: 0.4rem;
}

.paper-title {
    font-size: clamp(1.25rem, 1.02rem + 0.85vw, 1.75rem);
    line-height: 1.16;
    letter-spacing: -0.02em;
    max-width: 34ch;
}

.paper-authors {
    margin-top: 0.7rem;
    font-size: var(--t-base);
    color: var(--ink-2);
}

.paper-authors strong {
    font-weight: 600;
    color: var(--ink);
}

/* Stands in for the byline: an authorship signal without a list. */
.paper-credit {
    margin-top: 0.7rem;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-2);
}

/* The full citation — conference, city, series volume. */
.paper-detail {
    margin-top: 0.5rem;
    font-family: var(--font-data);
    font-size: var(--t-xs);
    line-height: 1.55;
    color: var(--ink-3);
    max-width: 52ch;
}

.paper-summary {
    margin-top: 0.9rem;
    color: var(--ink-2);
    font-size: var(--t-base);
    max-width: 58ch;
}

.paper-link {
    margin-top: 1.25rem;
}

@media (max-width: 46rem) {
    .paper-item {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.5rem;
    }

    .paper-stamp {
        padding-top: 0;
    }
}

/* ---------------------------------------------------------
   9. Talks
   ---------------------------------------------------------
   Videos are facades: a still frame and a play control, with
   the real iframe swapped in only on click. Three eager
   YouTube embeds cost roughly a megabyte before anyone has
   asked to watch anything.
   --------------------------------------------------------- */
.video {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--paper-3);
    border: 1px solid var(--rule);
    overflow: hidden;
}

.video iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.video-facade {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    display: block;
}

.video-facade img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(0.9);
    transition: transform 0.4s ease, filter 0.3s ease;
}

.video-facade:hover img {
    transform: scale(1.03);
    filter: saturate(1);
}

.video-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.05));
}

.video-play::before {
    content: '';
    width: 4.25rem;
    height: 4.25rem;
    border-radius: 50%;
    background: rgba(20, 18, 14, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.55);
    backdrop-filter: blur(2px);
    transition: background-color 0.2s ease, transform 0.2s ease;
}

.video-play::after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    border-left: 1.05rem solid #fff;
    border-top: 0.65rem solid transparent;
    border-bottom: 0.65rem solid transparent;
    margin-left: 0.25rem;
}

.video-facade:hover .video-play::before {
    background: var(--accent);
    transform: scale(1.06);
}

.talk-featured {
    margin-bottom: clamp(2rem, 4vw, 3rem);
}

.talk-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: clamp(1.25rem, 3vw, 2.25rem);
}

.talk figcaption {
    margin-top: 0.9rem;
}

.talk-source {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
}

.talk-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--t-base);
    line-height: 1.25;
    margin-top: 0.35rem;
}

.talk-desc {
    margin-top: 0.4rem;
    font-size: 0.95rem;
    color: var(--ink-2);
}

.talk-posts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0;
    border-top: 1px solid var(--rule);
    margin-top: clamp(2rem, 4vw, 3rem);
}

.talk-post {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.75rem 1.5rem 1.75rem 0;
    border-bottom: 1px solid var(--rule);
    text-decoration: none;
    color: inherit;
    transition: background-color 0.2s ease;
}

.talk-post + .talk-post {
    border-left: 1px solid var(--rule);
    padding-left: 1.5rem;
}

.talk-post:hover {
    background: var(--tint);
    color: inherit;
}

.talk-post-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.talk-post-label svg {
    width: 0.9rem;
    height: 0.9rem;
    color: var(--ink-2);
}

.talk-post h3 {
    font-size: var(--t-base);
    font-weight: 600;
}

.talk-post p {
    font-size: 0.95rem;
    color: var(--ink-2);
    flex: 1;
}

.talk-post .more-link {
    align-self: flex-start;
    margin-top: 0.5rem;
    border-bottom-color: transparent;
    padding-bottom: 0;
}

.talk-post:hover .more-link {
    color: var(--accent);
}

/* ---------------------------------------------------------
   10. The shelf
   ---------------------------------------------------------
   Books have no cover art here, so the shelf is drawn: each
   title becomes a cloth-bound spine whose colour is set by
   its genre, whose width follows the length of the title,
   and whose height varies just enough that a row of them
   reads as books rather than as a bar chart. The board line
   under every row is painted by a repeating gradient keyed
   to --spine-h, so the geometry can never drift.
   --------------------------------------------------------- */
.shelf {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    column-gap: 5px;
    row-gap: var(--shelf-row-gap);
    /* Leaves room inside the box for the board under the last row,
       which would otherwise fall outside the painted area. */
    padding-bottom: 4px;
    background-image: repeating-linear-gradient(
        to bottom,
        transparent 0,
        transparent var(--spine-h),
        var(--board) var(--spine-h),
        var(--board) calc(var(--spine-h) + 4px),
        transparent calc(var(--spine-h) + 4px),
        transparent calc(var(--spine-h) + var(--shelf-row-gap))
    );
}

.spine {
    /* --h is a 0–1 factor on the row height; --w a pixel width;
       --cloth the binding colour. All three are set inline by
       app.js from a hash of the title, so a book always looks
       the same on every visit. */
    position: relative;
    flex: 0 0 auto;
    width: var(--w, 48px);
    height: calc(var(--spine-h) * var(--h, 1));
    background: var(--cloth, #3a3a3a);
    background-image: linear-gradient(
        to right,
        rgba(0, 0, 0, 0.3) 0%,
        rgba(255, 255, 255, 0.1) 12%,
        rgba(255, 255, 255, 0.03) 45%,
        rgba(0, 0, 0, 0.18) 88%,
        rgba(0, 0, 0, 0.34) 100%
    );
    border: 0;
    border-radius: 1px 3px 3px 1px;
    box-shadow: var(--spine-shadow);
    color: rgba(255, 255, 255, 0.94);
    font-family: var(--font-display);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-block: 1.3rem;
    text-decoration: none;
    -webkit-appearance: none;
    appearance: none;
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.22s ease;
}

/* The two stamped bands near head and tail of the spine. */
.spine::before,
.spine::after {
    content: '';
    position: absolute;
    left: 4px;
    right: 4px;
    height: 1px;
    background: rgba(255, 255, 255, 0.34);
}

.spine::before { top: 0.85rem; }
.spine::after { bottom: 0.85rem; }

.spine-text {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-height: 100%;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Pulled halfway out of the shelf on hover. */
.spine:hover,
.spine:focus-visible {
    transform: translateY(-14px);
    box-shadow: 4px 16px 22px rgba(22, 19, 13, 0.28);
    z-index: 2;
}

/* A gilt dot marks the books there is something written about —
   a note, a full page, or both. Same mark is used in the index. */
.spine.has-writing::after {
    height: 4px;
    width: 4px;
    left: 50%;
    right: auto;
    bottom: 0.7rem;
    transform: translateX(-50%);
    border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}

.shelf-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.1rem;
    margin-top: 2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--rule);
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.swatch {
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 1px;
    background: var(--cloth);
    flex: none;
}

/* --- Index (list) view of the same shelf --- */
.book-index {
    list-style: none;
    border-top: 1px solid var(--ink);
}

.book-index-head,
.book-row {
    display: grid;
    grid-template-columns: 3rem minmax(0, 2fr) minmax(0, 1.3fr) 7.5rem 6.5rem 4.5rem;
    gap: 1rem;
    align-items: baseline;
    padding-block: 0.9rem;
    border-bottom: 1px solid var(--rule);
    text-align: left;
}

.book-index-head {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
    border-bottom-color: var(--rule-2);
    padding-block: 0.7rem;
}

/* The row is a button onto the book dialog, so it needs the usual
   button reset — but keeps its bottom rule. */
.book-row {
    width: 100%;
    color: inherit;
    font: inherit;
    /* Renders as either <button> or <a>, so it resets both. */
    text-decoration: none;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule);
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    transition: background-color 0.15s ease;
}

.book-row:hover {
    background: var(--tint);
}

.book-num {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    color: var(--ink-3);
    font-feature-settings: 'tnum' 1;
}

.book-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--t-base);
    line-height: 1.3;
}

.book-title .roman {
    color: var(--ink-3);
    font-weight: 400;
    font-style: italic;
}

.book-row:hover .book-title {
    color: var(--accent);
}

/* The gilt dot again, inline after a title in the index view. */
.mark {
    display: inline-block;
    width: 0.3rem;
    height: 0.3rem;
    border-radius: 50%;
    background: var(--gold);
    margin-left: 0.45em;
    vertical-align: 0.25em;
}

/* Stars. One layer of outlines, one clipped layer of fills, so a
   half rating really is half a star wide. */
.rating {
    position: relative;
    display: inline-block;
    font-size: 0.8rem;
    letter-spacing: 0.14em;
    line-height: 1;
    color: var(--rule-2);
    white-space: nowrap;
}

.rating::before {
    content: '★★★★★';
}

.rating-fill {
    position: absolute;
    top: 0;
    left: 0;
    overflow: hidden;
    white-space: nowrap;
    color: var(--star);
}

.rating-fill::before {
    content: '★★★★★';
}

.book-author {
    font-size: 0.95rem;
    color: var(--ink-2);
}

.book-genre {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-2);
}

.book-lang {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* --- Shelf toolbar --- */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    padding-block: 1.1rem;
    border-top: 1px solid var(--ink);
    border-bottom: 1px solid var(--rule);
    margin-bottom: 1.75rem;
}

.search {
    flex: 1 1 16rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border: 1px solid var(--rule-2);
    background: var(--paper-2);
    padding: 0.55rem 0.85rem;
}

.search svg {
    width: 0.95rem;
    height: 0.95rem;
    color: var(--ink-3);
    flex: none;
}

.search input {
    flex: 1;
    border: 0;
    background: transparent;
    font-family: var(--font-data);
    font-size: var(--t-sm);
    color: var(--ink);
    min-width: 0;
}

.search input:focus {
    outline: none;
}

.search input::placeholder {
    color: var(--ink-3);
}

.segmented {
    display: inline-flex;
    border: 1px solid var(--rule-2);
}

.segmented button {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.62rem 0.95rem;
    border: 0;
    background: transparent;
    color: var(--ink-3);
    cursor: pointer;
    transition: background-color 0.16s ease, color 0.16s ease;
}

.segmented button + button {
    border-left: 1px solid var(--rule-2);
}

.segmented button[aria-pressed='true'] {
    background: var(--ink);
    color: var(--paper);
}

.select {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0.62rem 0.85rem;
    border: 1px solid var(--rule-2);
    background: var(--paper-2);
    color: var(--ink-2);
    cursor: pointer;
}

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: 1.75rem;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.4rem 0.7rem;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
    transition: border-color 0.16s ease, color 0.16s ease, background-color 0.16s ease;
}

.chip:hover {
    border-color: var(--ink-3);
    color: var(--ink);
}

.chip[aria-pressed='true'] {
    border-color: var(--ink);
    background: var(--ink);
    color: var(--paper);
}

.chip-count {
    font-size: 0.9em;
    opacity: 0.65;
    font-feature-settings: 'tnum' 1;
}

.result-count {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-left: auto;
}

.empty {
    padding: 4rem 0;
    text-align: center;
    color: var(--ink-3);
    font-family: var(--font-data);
    font-size: var(--t-sm);
}

/* ---------------------------------------------------------
   11. Page headers (interior pages)
   --------------------------------------------------------- */
.page-head {
    padding-top: clamp(3rem, 6vw, 5rem);
    padding-bottom: clamp(2rem, 4vw, 3.5rem);
}

.page-head .kicker {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 1.25rem;
}

.page-head h1 {
    font-size: var(--t-2xl);
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 1;
    max-width: 18ch;
}

.page-head .lede {
    margin-top: 1.25rem;
    font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.25rem);
    color: var(--ink-2);
    max-width: 52ch;
}

/* ---------------------------------------------------------
   12. Article
   --------------------------------------------------------- */
.progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 2px;
    width: 100%;
    transform: scaleX(0);
    transform-origin: 0 50%;
    background: var(--accent);
    z-index: 60;
}

.article-head {
    padding-top: clamp(3rem, 6vw, 5rem);
    padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

.article-head h1 {
    font-size: clamp(2rem, 1.4rem + 2.6vw, 3.4rem);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.03em;
    font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 1;
    max-width: 20ch;
}

.article-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
    margin-top: 1.5rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.article-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
    padding-bottom: clamp(3rem, 6vw, 5rem);
}

@media (min-width: 62rem) {
    .article-layout {
        grid-template-columns: 13rem minmax(0, 1fr);
    }

    /* The header runs on the same grid so the title's left edge
       lines up with the text below it rather than with the rail. */
    .article-head {
        display: grid;
        grid-template-columns: 13rem minmax(0, 1fr);
        gap: clamp(2rem, 5vw, 4rem);
    }

    .article-head > * {
        grid-column: 2;
    }
}

/* Contents rail — a collapsible summary on small screens,
   a sticky spied list on wide ones. */
.toc {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    align-self: start;
}

@media (min-width: 62rem) {
    .toc {
        position: sticky;
        top: 6rem;
    }
}

.toc-title {
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding-bottom: 0.8rem;
    border-bottom: 1px solid var(--rule);
    cursor: pointer;
    list-style: none;
}

.toc-title::-webkit-details-marker {
    display: none;
}

.toc ol {
    list-style: none;
    counter-reset: toc;
    margin-top: 0.9rem;
}

.toc li {
    counter-increment: toc;
}

.toc a {
    display: flex;
    gap: 0.7rem;
    padding-block: 0.5rem;
    color: var(--ink-2);
    text-decoration: none;
    line-height: 1.4;
    transition: color 0.16s ease;
}

.toc a::before {
    content: counter(toc, decimal-leading-zero);
    color: var(--ink-3);
    flex: none;
}

.toc a:hover,
.toc a.is-active {
    color: var(--accent);
}

.toc a.is-active::before {
    color: var(--accent);
}

.prose {
    max-width: var(--measure);
    font-size: 1.2rem;
    line-height: 1.72;
}

.prose > p + p {
    margin-top: 1.35em;
}

/* A raised initial on the opening paragraph — the one piece
   of ornament the essay gets. */
.prose > p:first-of-type::first-letter {
    float: left;
    font-family: var(--font-display);
    font-size: 3.9em;
    line-height: 0.82;
    font-weight: 700;
    padding-right: 0.09em;
    margin-top: 0.06em;
    color: var(--accent);
    font-variation-settings: 'opsz' 144, 'WONK' 1;
}

.prose h2 {
    font-size: clamp(1.4rem, 1.15rem + 1vw, 1.9rem);
    font-weight: 600;
    letter-spacing: -0.02em;
    margin-top: 2.6em;
    margin-bottom: 0.7em;
    padding-top: 0.9rem;
    border-top: 1px solid var(--rule);
    max-width: 24ch;
}

.prose h3 {
    font-size: 1.25rem;
    margin-top: 2em;
    margin-bottom: 0.5em;
}

.prose ul,
.prose ol {
    margin: 1.5em 0;
    padding-left: 1.4em;
}

.prose li {
    margin-bottom: 0.5em;
    padding-left: 0.35em;
}

.prose ul li::marker {
    color: var(--accent);
}

.prose ol li::marker {
    font-family: var(--font-data);
    font-size: 0.85em;
    color: var(--ink-3);
}

.prose blockquote {
    margin: 2em 0;
    padding-left: 1.5rem;
    border-left: 2px solid var(--accent);
    font-style: italic;
    color: var(--ink-2);
}

.prose strong {
    font-weight: 600;
}

.prose hr {
    border: 0;
    border-top: 1px solid var(--rule);
    margin: 3em 0;
}

.article-end {
    max-width: var(--measure);
    margin-top: 3.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--ink);
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
}

.article-end .byline {
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* Book summary pages reuse .prose but open with a colophon
   block naming the author and genre. */
.book-colophon {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1.5rem;
    align-items: center;
    margin-top: 1.5rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* ---------------------------------------------------------
   13. Contact
   --------------------------------------------------------- */
.contact {
    border-top: 1px solid var(--ink);
    padding-block: clamp(3.5rem, 7vw, 6rem);
}

.contact h2 {
    font-size: var(--t-2xl);
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 1;
    max-width: 16ch;
}

.contact h2 em {
    color: var(--accent);
    font-weight: 500;
}

.contact p {
    margin-top: 1.25rem;
    color: var(--ink-2);
    max-width: 46ch;
}

.contact-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 2rem;
}

/* ---------------------------------------------------------
   14. Footer
   --------------------------------------------------------- */
.site-footer {
    border-top: 1px solid var(--rule);
    padding-block: clamp(2.5rem, 5vw, 4rem) 2rem;
    margin-top: auto;
}

.footer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 2.5rem;
    padding-bottom: 2.5rem;
}

.footer-col h2 {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 1rem;
}

.footer-col ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.footer-col a {
    font-size: 0.95rem;
    color: var(--ink-2);
    text-decoration: none;
    transition: color 0.16s ease;
    /* Padded to a 24px target rather than the 15px the line box gives,
       so these clear WCAG 2.5.8 on a phone. */
    display: inline-block;
    padding-block: 0.25rem;
}

.footer-col a:hover {
    color: var(--accent);
}

.footer-bio {
    font-size: 0.9rem;
    color: var(--ink-2);
    line-height: 1.6;
    max-width: 34ch;
}

.footer-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    padding-top: 1.5rem;
    border-top: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.footer-bar a {
    color: var(--ink-3);
    text-decoration: none;
    display: inline-block;
    padding-block: 0.25rem;
}

.footer-bar a:hover {
    color: var(--accent);
}

.social {
    display: flex;
    gap: 0.5rem;
}

.social a {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--rule);
    color: var(--ink-2);
    transition: color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.social a:hover {
    color: var(--accent);
    border-color: var(--accent);
    transform: translateY(-2px);
}

.social svg {
    width: 0.95rem;
    height: 0.95rem;
}

/* ---------------------------------------------------------
   15. Section rail (desktop only)
   --------------------------------------------------------- */
.rail {
    position: fixed;
    top: 50%;
    right: clamp(0.75rem, 1.6vw, 1.5rem);
    transform: translateY(-50%);
    z-index: 40;
    display: none;
    flex-direction: column;
    gap: 0.15rem;
}

@media (min-width: 82rem) {
    .rail {
        display: flex;
    }
}

.rail a {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.6rem;
    padding: 0.4rem 0;
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
    text-decoration: none;
    transition: color 0.18s ease;
}

.rail a span {
    opacity: 0;
    transform: translateX(4px);
    transition: opacity 0.18s ease, transform 0.18s ease;
}

.rail:hover a span,
.rail a.is-active span {
    opacity: 1;
    transform: none;
}

.rail a::after {
    content: '';
    width: 1.4rem;
    height: 1px;
    background: currentColor;
    flex: none;
    transition: width 0.18s ease;
}

.rail a:hover,
.rail a.is-active {
    color: var(--accent);
}

.rail a.is-active::after {
    width: 2.4rem;
}

/* ---------------------------------------------------------
   16. Dialog (book notes)
   --------------------------------------------------------- */
.dialog {
    /* The global `* { margin: 0 }` reset wipes out the UA's
       `margin: auto`, which is what centres a modal dialog. */
    margin: auto;
    max-width: 34rem;
    width: calc(100% - 2rem);
    border: 1px solid var(--rule-2);
    background: var(--paper-2);
    color: var(--ink);
    padding: clamp(1.5rem, 4vw, 2.5rem);
    box-shadow: var(--lift);
}

.dialog::backdrop {
    background: rgba(20, 18, 14, 0.5);
    backdrop-filter: blur(3px);
}

.dialog-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    width: 2rem;
    height: 2rem;
    border: 0;
    background: transparent;
    color: var(--ink-3);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.dialog-close:hover {
    color: var(--accent);
}

.dialog-kicker {
    font-family: var(--font-data);
    font-size: var(--t-2xs);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 0.85rem;
}

.dialog-title {
    font-size: var(--t-lg);
    padding-right: 2rem;
    line-height: 1.2;
}

.dialog-title .roman {
    color: var(--ink-3);
    font-weight: 400;
    font-style: italic;
}

.dialog-credit {
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: var(--t-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.dialog-rating {
    margin-top: 0.9rem;
}

.dialog-rating .rating {
    font-size: 1.05rem;
}

.dialog-body {
    margin-top: 1.25rem;
    color: var(--ink);
    font-size: var(--t-md);
}

.dialog-empty {
    margin-top: 1.25rem;
    font-family: var(--font-data);
    font-size: var(--t-sm);
    color: var(--ink-3);
}

.dialog-link {
    margin-top: 1.75rem;
}

/* ---------------------------------------------------------
   17. Responsive
   --------------------------------------------------------- */
@media (max-width: 62rem) {
    .masthead-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .plate {
        max-width: 22rem;
    }

    .figures {
        grid-template-columns: repeat(2, 1fr);
    }

    .figure:nth-child(3) {
        border-left: 0;
        padding-left: 0;
    }

    .figure:nth-child(n + 3) {
        border-top: 1px solid var(--rule);
    }

    /* Author folds under the title and the binding drops away; the
       rating keeps its own column, since it is the reason to scan
       this view in the first place. */
    .book-index-head,
    .book-row {
        grid-template-columns: 2.5rem minmax(0, 1fr) 6.5rem;
        gap: 0.15rem 1rem;
    }

    .book-num {
        grid-column: 1;
        grid-row: 1;
    }

    .book-title {
        grid-column: 2;
        grid-row: 1;
    }

    .book-author {
        grid-column: 2;
        grid-row: 2;
    }

    .col-rating {
        grid-column: 3;
        grid-row: 1;
    }

    .book-index-head .col-author,
    .col-genre,
    .col-lang {
        display: none;
    }
}

@media (max-width: 46rem) {
    :root {
        --spine-h: 200px;
        --shelf-row-gap: 32px;
    }

    .ledger-row,
    .post-index a {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.5rem;
    }

    .talk-post + .talk-post {
        border-left: 0;
        padding-left: 0;
    }

    .talk-post {
        padding-right: 0;
    }

    .spine {
        font-size: 0.7rem;
    }
}

@media (max-width: 34rem) {
    .figures {
        grid-template-columns: minmax(0, 1fr);
    }

    .figure {
        border-left: 0;
        padding-left: 0;
        border-top: 1px solid var(--rule);
    }

    .figure:first-child {
        border-top: 0;
    }

    .book-index-head,
    .book-row {
        grid-template-columns: 2rem minmax(0, 1fr) 5.5rem;
    }

    .rating {
        font-size: 0.72rem;
        letter-spacing: 0.1em;
    }
}

/* ---------------------------------------------------------
   18. Motion & print
   --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

@media print {
    .topbar,
    .rail,
    .progress,
    .site-footer,
    .toc,
    .toolbar,
    .chips {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
        font-size: 11pt;
    }

    .prose {
        max-width: none;
    }

    .prose h2 {
        break-after: avoid;
    }

    a[href^='http']::after {
        content: ' (' attr(href) ')';
        font-size: 9pt;
        color: #555;
    }
}
