/* components.css — Nav, TOC, metadata block, page footer.
   Loaded on every page. */

/* ============================================================
   SKIP LINK
   ============================================================ */

.skip-link {
    position: absolute;
    top: -100%;
    left: 0;
    z-index: 9999;
    padding: 0.5em 1em;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    text-decoration: none;
    font-size: 0.875rem;
}

.skip-link:focus {
    top: 0;
}

/* ============================================================
   NAV
   Two-row: primary links (always visible) + portal links
   (collapsed by default, expanded via nav.js + localStorage).
   ============================================================ */

nav.site-nav {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    font-family: var(--font-sans);
}

/* Row 1: centered primary links + right-side controls */
.nav-row-primary {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0.65rem 1.5rem;
}

.nav-primary {
    display: flex;
    align-items: center;
    gap: 0;
    font-size: 0.8rem;
    font-weight: 600;
    font-variant-caps: small-caps;
    letter-spacing: 0.06em;
}

.nav-primary a {
    text-decoration: none;
    color: var(--text-muted);
    padding: 0.15rem 0.85rem;
    transition: color var(--transition-fast);
}

.nav-primary a:hover {
    color: var(--text);
}

.nav-primary a + a {
    border-left: 1px solid var(--border);
}

/* Home logo — square button flush into the top-left corner of the nav bar.
   The rooted-L mark is inlined (templates/partials/logo-mark.svg) so its
   two-tone cutout renders: the letter is drawn in --logo-ink and the root
   filament is punched through in --logo-bg. Mapping --logo-bg to --bg-nav
   (the button's own surface) makes the roots read as the nav background
   showing through. Both tokens are theme-driven in base.css — override
   --nav-logo-fg / --bg-nav there to restyle per theme. */
.nav-logo {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
    text-decoration: none;
    background-color: var(--bg-nav);
    --logo-ink: var(--nav-logo-fg);
    --logo-bg: var(--bg-nav);
}
.nav-logo__mark {
    width: 76%;
    height: 76%;
    display: block;
}

/* Controls cluster: portals toggle + theme toggle, pinned right */
.nav-controls {
    position: absolute;
    right: 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.nav-portal-toggle {
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.06em;
    color: var(--text-faint);
    padding: 0;
    line-height: 1;
    transition: color var(--transition-fast);
    white-space: nowrap;
}
.nav-portal-toggle:hover {
    color: var(--text-muted);
}

.nav-portal-arrow {
    font-size: 0.6rem;
    display: inline-block;
    margin-right: 0.2em;
    vertical-align: middle;
}

/* Settings button + panel */
.settings-wrap {
    position: relative;
}

.settings-toggle {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-faint);
    font-size: 0.85rem;
    font-family: var(--font-sans);
    padding: 0;
    line-height: 1;
    transition: color var(--transition-fast);
}
.settings-toggle:hover,
.settings-toggle[aria-expanded="true"] {
    color: var(--text-muted);
}

.settings-panel {
    position: absolute;
    top: calc(100% + 0.6rem);
    right: 0;
    z-index: 800;
    min-width: 148px;
    padding: 0.5rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);

    display: none;
    flex-direction: column;
    gap: 0.1rem;
}

.settings-panel.is-open {
    display: flex;
}

.settings-section {
    padding: 0.3rem 0.2rem;
}
.settings-section + .settings-section {
    border-top: 1px solid var(--border);
    padding-top: 0.4rem;
    margin-top: 0.1rem;
}

.settings-label {
    font-family: var(--font-sans);
    font-size: 0.62rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.07em;
    color: var(--text-faint);
    margin-bottom: 0.3rem;
    line-height: 1;
}

.settings-row {
    display: flex;
    gap: 0.3rem;
}

.settings-btn {
    flex: 1;
    background: var(--bg-offset);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--text-muted);
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-weight: 500;
    padding: 0.3rem 0.5rem;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                border-color var(--transition-fast);
    white-space: nowrap;
    line-height: 1.2;
}
.settings-btn:hover:not(:disabled) {
    background: var(--border);
    color: var(--text);
}
.settings-btn.is-active {
    background: var(--text);
    border-color: var(--text);
    color: var(--bg);
}
.settings-btn:disabled {
    opacity: 0.35;
    cursor: default;
}
.settings-btn--full {
    width: 100%;
    flex: none;
    text-align: center;
}

.settings-btn--danger {
    color: rgba(180, 80, 80, 0.85);
}
.settings-btn--danger:hover {
    color: rgba(180, 80, 80, 1);
}

.settings-col {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}


/* ============================================================
   FOCUS MODE — header hide
   TOC hide lives in layout.css.
   Settings gear stays accessible at top-right.
   ============================================================ */

[data-focus-mode] body > header .site-nav {
    visibility: hidden;
    height: 0;
    overflow: hidden;
}

[data-focus-mode] .settings-wrap {
    visibility: visible;
    position: fixed;
    top: 0.75rem;
    right: 1.25rem;
    z-index: 1000;
}

[data-focus-mode] .settings-panel {
    position: fixed;
    top: 2.5rem;
    right: 1.25rem;
}


/* ============================================================
   REDUCE MOTION
   Collapses all transitions and animations site-wide.
   Applied to <html> before first paint by theme.js.
   ============================================================ */

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

/* Mobile TOC bar — hidden by default; revealed whenever the desktop
   TOC sidebar is hidden (see layout.css: #toc hides at ≤900px).
   Declared here (before the media queries) so source-order cascade
   lets the mobile rules win. */
#toc-mobile-bar {
    display: none;
}

/* ── Mobile TOC bar (≤900px — mirrors #toc hide breakpoint) ──────────
   Fixed bottom strip: progress line + current section label.
   toc.js sets --toc-progress and syncs the label. Uses (max-width)
   rather than (pointer: coarse) so Android's "request desktop site"
   mode — which fakes a ~980px viewport — correctly shows the desktop
   sidebar TOC instead of this bar.
   ──────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
    /* Bottom padding so the last content line isn't hidden
       behind the fixed mobile TOC bar. */
    body {
        padding-bottom: 2.5rem;
    }

    #toc-mobile-bar {
        display: flex;
        align-items: center;
        position: fixed;
        bottom: 0; left: 0; right: 0;
        height: 2.25rem;
        background: var(--bg-nav);
        border-top: 1px solid var(--border);
        padding: 0 1rem;
        z-index: 90;
        overflow: hidden;
    }

    /* Progress track (faint full-width line at top of bar) */
    #toc-mobile-bar::before {
        content: '';
        position: absolute;
        top: 0; left: 0; right: 0;
        height: 2px;
        background: var(--border);
    }

    /* Progress fill — grows with scroll via --toc-progress */
    #toc-mobile-bar::after {
        content: '';
        position: absolute;
        top: 0; left: 0;
        height: 2px;
        width: calc(var(--toc-progress, 0) * 100%);
        background: var(--text-muted);
        transition: width 0.12s ease;
    }

    .toc-mobile-label {
        font-family: var(--font-sans);
        font-size: 0.68rem;
        font-weight: 600;
        font-variant-caps: all-small-caps;
        letter-spacing: 0.07em;
        color: var(--text-faint);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* ── Mobile nav (≤540px) ─────────────────────────────────────────────
   Controls are position:absolute on desktop (out of flex flow, pinned
   right). On narrow viewports they collide with the primary links.
   Fix: bring them into flow, wrap the row, add a separator line.
   ──────────────────────────────────────────────────────────────────── */

@media (max-width: 540px) {
    .nav-logo {
        display: none;
    }

    .nav-row-primary {
        flex-wrap: wrap;
        justify-content: center;
        padding: 0.4rem 0.75rem;
        gap: 0.25rem 0;
    }

    .nav-primary {
        flex-wrap: wrap;
        justify-content: center;
        font-size: 0.72rem;
    }

    /* Larger vertical padding → usable tap targets without extra markup */
    .nav-primary a {
        padding: 0.35rem 0.55rem;
    }

    /* border-left separators look broken on wrapped rows (the first link
       of a new row still gets a left border). Replace with a gap. */
    .nav-primary a + a {
        border-left: none;
        margin-left: 0.1rem;
    }

    /* Pull controls out of absolute positioning, span full width, center */
    .nav-controls {
        position: static;
        width: 100%;
        justify-content: center;
        padding-top: 0.3rem;
        border-top: 1px solid var(--border);
        margin-top: 0.15rem;
    }

    .nav-portal-toggle {
        padding: 0.3rem 0;
    }

    /* Portal row: tighter side padding on narrow screens */
    .nav-portals {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    .nav-portals a {
        padding: 0.3rem 0.55rem;
    }
}

/* Row 2: portal links — hidden until nav.js adds .is-open */
.nav-portals {
    display: none;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0;
    padding: 0.4rem 1.5rem 0.5rem;
    border-top: 1px solid var(--border);
}

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

.nav-portals a {
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.05em;
    text-decoration: none;
    color: var(--text-faint);
    padding: 0.1rem 0.7rem;
    transition: color var(--transition-fast);
}
.nav-portals a + a {
    border-left: 1px solid var(--border);
}
.nav-portals a:hover {
    color: var(--text);
}


/* ============================================================
   TABLE OF CONTENTS
   Sticky left sidebar (position: sticky set in layout.css).
   toc.js manages: .is-active links, .is-collapsed state,
   and the --toc-progress custom property for the progress bar.
   ============================================================ */

#toc {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    line-height: 1.5;
    padding-right: 1.5rem;
    padding-left: 0.5rem;
}

/* Header row: current section label + collapse toggle */
.toc-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    padding-bottom: 0.55rem;
    margin-bottom: 0.35rem;
    position: relative;
}

/* Progress track — full width, faint */
.toc-header::before {
    content: '';
    position: absolute;
    bottom: 0; left: 0;
    width: 100%; height: 1px;
    background: var(--border);
}

/* Progress fill — grows left→right with scroll */
.toc-header::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0;
    height: 1px;
    width: calc(var(--toc-progress, 0) * 100%);
    background: var(--text-muted);
    transition: width 0.12s ease;
}

/* Current section label */
.toc-active-label {
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.07em;
    color: var(--text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1;
}

#toc.is-collapsed .toc-active-label {
    color: var(--text-muted);
}

/* Collapse toggle button */
.toc-toggle {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-faint);
    font-size: 0.72rem;
    padding: 0;
    line-height: 1;
    flex-shrink: 0;
    transition: color var(--transition-fast), transform 0.28s ease;
}
.toc-toggle:hover {
    color: var(--text-muted);
}
#toc.is-collapsed .toc-toggle {
    transform: rotate(-90deg);
}

/* Nav: animates open/closed via max-height. The collapsed state hides
   the nav from the keyboard tab order *and* the accessibility tree
   using `aria-hidden="true"` (set by toc.js). The transition still
   works because we keep `max-height: 0` for the visual collapse. */
.toc-nav {
    /* Fill the sticky sidebar's remaining height and scroll when the
       outline is taller than the viewport. The subtracted ~2.6rem
       mirrors #toc's own max-height budget (layout.css) minus the
       .toc-header row (label + progress rule + its bottom margin). */
    max-height: calc(100vh - var(--nav-height, 4rem) - 3rem - 2.6rem);
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    transition: max-height 0.3s ease;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.toc-nav::-webkit-scrollbar { width: 6px; }
.toc-nav::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 3px;
}
#toc.is-collapsed .toc-nav {
    max-height: 0;
    /* overflow:hidden so the outline is clipped (not scrolled) while
       the max-height transition runs down to 0. */
    overflow: hidden;
}
#toc.is-collapsed .toc-nav a,
#toc.is-collapsed .toc-nav button {
    /* Belt-and-suspenders: even if aria-hidden is somehow stripped,
       the collapsed nav cannot receive focus. The earlier rule used
       `visibility: hidden` which already removed elements from the
       focus order, but `visibility` interacts poorly with the
       max-height transition; tabindex=-1 set by toc.js is preferred. */
    pointer-events: none;
}

/* Nav list */
.toc-nav ol {
    list-style: none;
    padding: 0;
    margin: 0;
}

.toc-nav > ol > li {
    margin: 0.3rem 0;
}

.toc-nav > ol > li > ol {
    margin: 0.1rem 0 0.2rem 0;
}
.toc-nav > ol > li > ol > li {
    margin: 0.15rem 0;
}

.toc-nav a {
    text-decoration: none;
    color: var(--text-faint);
    display: block;
    padding: 0.1rem 0;
    transition: color var(--transition-fast);
}
.toc-nav a:hover {
    color: var(--text);
}

/* JS adds .is-active to the current heading's link */
.toc-nav a.is-active {
    color: var(--text);
    font-weight: 600;
}

/* h2-level links slightly more prominent */
.toc-nav > ol > li > a {
    color: var(--text-muted);
}
.toc-nav > ol > li > a:hover,
.toc-nav > ol > li > a.is-active {
    color: var(--text);
}

/* h3-level links indented and smaller */
.toc-nav > ol > li > ol > li > a {
    padding-left: 0.75rem;
    font-size: 0.74rem;
}


/* ============================================================
   PAGE TITLE
   ============================================================ */

.page-title {
    font-family: var(--font-sans);
    font-size: 2.6rem;
    font-weight: 600;
    margin: 0 0 1.65rem 0;
    line-height: 1.1;
    color: var(--text);
}


/* ============================================================
   METADATA BLOCK
   Vertical sequence above the body: tags, description,
   authors (optional), jump links to bottom footer sections.
   ============================================================ */

.metadata {
    margin-bottom: 2.475rem;
    font-family: var(--font-sans);
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.meta-row {
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.5;
}

/* Tags, authors, jump links: centered */
.meta-tags,
.meta-authors,
.meta-pagelinks {
    text-align: center;
}

/* Description: blockquote style, left-aligned */
.meta-description {
    font-style: italic;
    padding-left: 1.25em;
    border-left: 2px solid var(--border);
    color: var(--text-muted);
}

/* Tags: centered row of small-caps links separated by middots */
.meta-tags {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0;
    color: var(--text-faint);
    font-size: 0.72rem;
}

.meta-tag {
    color: var(--text-faint);
    text-decoration: none;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.06em;
    transition: color var(--transition-fast);
}

.meta-tag:hover {
    color: var(--text-muted);
}

.meta-tag + .meta-tag::before {
    content: " · ";
    color: var(--text-faint);
    letter-spacing: 0;
    font-variant-caps: normal;
}

/* Affiliation: institution name below author, in sans to contrast the serif author row */
.meta-affiliation {
    font-family: var(--font-sans);
    font-size: 0.7rem;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    text-align: center;
}

.meta-affiliation a {
    color: var(--text-faint);
    text-decoration: none;
    transition: color var(--transition-fast);
}

.meta-affiliation a:hover {
    color: var(--text-muted);
}

/* Authors: "by" label + name */
.meta-authors {
    font-size: 0.78rem;
    color: var(--text-faint);
}
.meta-authors .meta-label {
    font-variant-caps: all-small-caps;
    font-weight: 600;
    letter-spacing: 0.06em;
    font-size: 0.68rem;
    color: var(--text-faint);
    margin-right: 0.4rem;
}

/* Jump links: inline, separated by middots */
.meta-pagelinks {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0;
    font-size: 0.75rem;
    color: var(--text-faint);
}
.meta-pagelinks a {
    color: var(--text-faint);
    text-decoration: none;
}
.meta-pagelinks a:hover {
    color: var(--text-muted);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.meta-pagelinks a + a::before {
    content: " · ";
    color: var(--border);
    display: inline-block;
    text-decoration: none;
    white-space: pre;
}

/* Top-of-page parallel tag strip — surfaces the full epistemic profile
   inline so a reader sees status, trust score, and every orientation
   axis at a glance, without scrolling to the footer. The trust chip
   anchors the left edge; status sits next to it; the labeled rows
   follow with their leading centerdot separators. Wraps freely. */
.meta-epistemic-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 0.35rem 0.55rem;
}


/* ============================================================
   ESSAY SUMMARY BOX
   Optional key-points / summary block rendered from the
   `summary:` frontmatter field, between metadata and content.
   ============================================================ */

.essay-summary {
    margin: 1.5rem 0 0;
    padding: 1.25rem 1.5rem;
    border-left: 3px solid var(--border-muted);
    background: var(--bg-offset, var(--bg));
    font-size: 0.92rem;
    line-height: 1.6;
}

.essay-summary-label {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.07em;
    color: var(--text-faint);
    margin-bottom: 0.5rem;
}

.essay-summary p {
    margin: 0 0 0.5em;
}

.essay-summary p:last-child {
    margin-bottom: 0;
}

/* ============================================================
   CONTENT DIVIDERS
   Decorative rule with centered logo. Used both at the top of
   the body (content-divider, between metadata and prose) and at
   the aftermatter boundary (aftermatter-divider).
   ============================================================ */

.content-divider,
.aftermatter-divider {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.content-divider {
    margin: 2rem 0 2.5rem;
}

.aftermatter-divider {
    margin: 3.5rem 0 2.5rem;
}

.content-divider::before,
.content-divider::after,
.aftermatter-divider::before,
.aftermatter-divider::after {
    content: '';
    flex: 1;
    border-top: 1px dashed var(--text-faint);
    opacity: 0.5;
}

.content-divider-logo,
.aftermatter-logo {
    display: block;
    width: 1.6rem;
    height: 1.6rem;
    flex-shrink: 0;
    background-color: var(--text-faint);
    opacity: 0.45;
    mask-image: url('/images/link-icons/internal.svg');
    mask-size: contain;
    mask-repeat: no-repeat;
    mask-position: center;
    -webkit-mask-image: url('/images/link-icons/internal.svg');
    -webkit-mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    transition: opacity var(--transition-fast);
}

.content-divider-logo:hover,
.aftermatter-logo:hover {
    opacity: 0.7;
}

/* ============================================================
   AFTERMATTER HEADINGS
   Right-aligned, all-small-caps, muted — visually distinct from
   main-body headings to signal supplementary material.
   ============================================================ */

.aftermatter :is(h2, h3, h4) {
    text-align: right;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.aftermatter h2 {
    font-size: 1.3rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--border-muted);
}

.aftermatter h3 {
    font-size: 1.05rem;
}

/* ============================================================
   FOOTER ORNAMENT
   Inline SVG floral ornament separating body from page metadata.
   Uses currentColor for automatic light/dark theming.
   ============================================================ */

.footer-ornament {
    display: block;
    width: 100%;
    height: auto;
    padding: 0.5rem var(--page-padding);
    color: var(--text-faint);
    opacity: 0.5;
}

/* ============================================================
   BOTTOM METADATA FOOTER
   Full-width section outside the essay's three-column layout.
   Structure: [Further Reading row?] [Bibliography row?] [metadata grid].
   ============================================================ */

.page-meta-footer {
    padding: 1.5rem var(--page-padding) 2rem;
    font-family: var(--font-sans);
    font-size: 0.82rem;
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
}

/* Each section is constrained and centered. */
.page-meta-footer > * {
    width: 100%;
    max-width: min(1200px, 100%);
}

/* Shared heading style for full-width section headings */
.meta-footer-full > h3,
.meta-footer-section h3 {
    font-size: 0.78rem;
    font-weight: 600;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.07em;
    color: var(--text-faint);
    margin: 0 0 0.75rem 0;
    font-family: var(--font-sans);
    text-rendering: optimizeLegibility;
}

/* Full-width rows: Further Reading and Bibliography */
.meta-footer-full {
    width: 100%;
}

/* Secondary row: RELATED | EPISTEMIC | VERSION HISTORY.
   auto-fit + minmax lets the grid render 3 columns when all are present,
   2 when RELATED is absent (zero similar pages), and stack gracefully
   at narrow viewports without any further media queries. */
.meta-footer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    justify-content: center;
    gap: 1.65rem 2.25rem;
    padding-top: 0.25rem;
}

.meta-footer-section p,
.meta-footer-section ul {
    margin: 0;
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.5;
}

.meta-footer-section ul {
    padding-left: 1em;
    list-style: none;
}

.meta-footer-section ul li::before {
    content: "–\00a0";
    color: var(--text-faint);
}

/* ============================================================
   BACKLINKS — promoted to a full-width aftermatter section.
   Each entry: source title in serif body face, then a blockquote of
   the sentence containing the link. A small "¶" affordance reveals
   the full paragraph in a hover/focus-activated popup.
   ============================================================ */

/* The "BACKLINKS" small-caps label is noticeably larger than the
   secondary-row headings (which stay at 0.78rem) because Backlinks
   is now a primary aftermatter section. */
.meta-footer-backlinks > h3 {
    font-size: 1.05rem;
    letter-spacing: 0.09em;
    margin-bottom: 1rem;
}

.meta-footer-backlinks .backlinks-list {
    padding: 0;
    margin: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.meta-footer-backlinks .backlinks-list li::before {
    content: none;
}

.backlink-item {
    padding: 0;
}

/* Source title — serif body face, prominent but restrained */
.backlink-source {
    display: inline-block;
    font-family: var(--font-serif);
    font-size: 1.32rem;
    font-variant: normal;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px solid var(--border-muted);
    padding-bottom: 0.05em;
    transition: color var(--transition-fast),
                border-color var(--transition-fast);
}

.backlink-source:hover,
.backlink-source:focus-visible {
    color: var(--text);
    border-color: var(--border);
}

/* Sentence-level context quoted beneath the title */
.backlink-quote {
    margin: 0.55rem 0 0 0;
    padding: 0 0 0 1rem;
    border-left: 2px solid var(--border-muted);
    font-family: var(--font-serif);
    font-size: 1.12rem;
    font-style: italic;
    line-height: 1.55;
    color: var(--text-muted);
    quotes: none;
}

.backlink-quote::before,
.backlink-quote::after {
    content: none;
}

.backlink-quote a {
    color: var(--text-muted);
    text-decoration-color: var(--border-muted);
}

.backlink-quote a:hover {
    color: var(--text);
    text-decoration-color: var(--border);
}

/* Hover/focus popup — full paragraph context */
.backlink-full {
    position: relative;
    display: inline-block;
    margin-left: 0.35em;
    vertical-align: baseline;
}

.backlink-full-trigger {
    background: none;
    border: 1px solid var(--border-muted);
    border-radius: 999px;
    width: 1.1rem;
    height: 1.1rem;
    padding: 0;
    line-height: 1;
    font-family: var(--font-sans);
    font-size: 0.72rem;
    color: var(--text-faint);
    cursor: help;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color var(--transition-fast),
                border-color var(--transition-fast),
                background-color var(--transition-fast);
}

.backlink-full-trigger:hover,
.backlink-full:focus-within .backlink-full-trigger {
    color: var(--text);
    border-color: var(--border);
    background-color: var(--bg-offset);
}

.backlink-full-popup {
    display: none;
    position: absolute;
    z-index: 200;
    bottom: calc(100% + 0.4rem);
    left: 0;
    width: min(34rem, 80vw);
    padding: 0.75rem 0.95rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 3px;
    box-shadow: 0 2px 14px rgba(0, 0, 0, 0.08);
    font-family: var(--font-serif);
    font-style: normal;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
    text-align: left;
}

.backlink-full:hover .backlink-full-popup,
.backlink-full:focus-within .backlink-full-popup {
    display: block;
}

.backlink-full-popup a {
    color: var(--text-muted);
    text-decoration-color: var(--border-muted);
}

.backlink-full-popup a:hover {
    color: var(--text);
}

/* ============================================================
   RELATED (SIMILAR LINKS) — promoted to a full-width aftermatter
   section, sitting just under Backlinks. Source file:
   data/similar-links.json (produced by tools/embed.py).
   ============================================================ */

.meta-footer-similar > h3 {
    font-size: 1.05rem;
    letter-spacing: 0.09em;
    margin-bottom: 1rem;
}

.meta-footer-similar .similar-links-list {
    padding: 0;
    margin: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.meta-footer-similar .similar-links-list li::before {
    content: none;
}

.meta-footer-similar .similar-links-item a {
    font-family: var(--font-serif);
    font-size: 1.18rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px solid var(--border-muted);
    padding-bottom: 0.05em;
    transition: color var(--transition-fast),
                border-color var(--transition-fast);
}

.meta-footer-similar .similar-links-item a:hover,
.meta-footer-similar .similar-links-item a:focus-visible {
    color: var(--text);
    border-bottom-color: var(--border);
}

/* ============================================================
   VERSION HISTORY — cap at 3 with a <details> "more" affordance.
   .version-history-list inherits list styling from .meta-footer-section ul.
   ============================================================ */

.version-history-more {
    margin-top: 0.35rem;
}

.version-history-more > summary {
    list-style: none;
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.06em;
    color: var(--text-faint);
    user-select: none;
    padding-left: 1em;
    transition: color var(--transition-fast);
}

.version-history-more > summary::-webkit-details-marker {
    display: none;
}

.version-history-more > summary::before {
    content: "▸\00a0";
    font-size: 0.7em;
    vertical-align: 0.1em;
}

.version-history-more[open] > summary::before {
    content: "▾\00a0";
}

.version-history-more > summary:hover {
    color: var(--text-muted);
}

.version-history-more > .version-history-list {
    margin-top: 0.25rem;
}


/* ============================================================
   EPISTEMIC METADATA BLOCK
   Compact display (status chip + confidence % + dot scales)
   with an expandable <details> for the full profile.
   ============================================================ */

/* Status chip */
.ep-status {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

/* Every labeled row beneath the primary line shares one class so new
   epistemic fields can be added in the template without touching CSS.
   Used by confidence, importance, evidence, scope, novelty, practicality. */
.ep-row {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    color: var(--text-faint);
}
.ep-row::before { content: "·\00a0"; color: var(--border); }

/* Dot scale (importance / evidence) — only ever used nested inside an
   .ep-row wrapper, which already supplies the centerdot separator. */
.ep-dots {
    font-size: 0.55rem;
    letter-spacing: 0.12em;
    color: var(--text-muted);
    line-height: 1;
    vertical-align: 0.15em;
}
.ep-row .ep-dots::before { content: none; }

/* Trust chip on the primary row — bordered numeric chip plus a small-caps
   "trust" label, mirroring .ep-status typography so the two sit together. */
.ep-trust {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-variant-caps: all-small-caps;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}
.ep-score {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-variant-caps: normal;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    border: 1px solid var(--border-muted);
    border-radius: 2px;
    padding: 0.05em 0.5em;
    margin-right: 0.25em;
}

/* Definition list for expanded profile */
.ep-expanded {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.2rem 0.75rem;
    margin: 0.5rem 0 0 0;
    font-size: 0.75rem;
    line-height: 1.45;
}

.ep-expanded dt {
    color: var(--text-faint);
    font-family: var(--font-sans);
    font-variant-caps: all-small-caps;
    letter-spacing: 0.04em;
}

.ep-expanded dd {
    margin: 0;
    color: var(--text-muted);
    font-family: var(--font-sans);
}


/* ============================================================
   PAGINATION NAV
   ============================================================ */

.paginate-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-muted);
    font-family: var(--font-sans);
}

.paginate-btn {
    color: var(--text-faint);
    text-decoration: none;
    font-size: 1rem;
    line-height: 1;
    transition: color var(--transition-fast);
}

.paginate-btn:hover {
    color: var(--text-muted);
}

.paginate-info {
    font-size: 0.75rem;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}


/* ============================================================
   CITATION MARKERS (inline superscripts)
   ============================================================ */

.cite-marker {
    font-family: var(--font-sans);
    font-size: 0.62em;
    line-height: 1;
    vertical-align: super;
    margin: 0 0.08em;
}

.cite-link {
    color: var(--text-faint);
    text-decoration: none;
    border: 1px solid var(--border-muted);
    border-radius: 2px;
    padding: 0.05em 0.28em;
    font-weight: 600;
    letter-spacing: 0.01em;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.cite-link:hover {
    color: var(--text-muted);
    border-color: var(--border);
    text-decoration: none;
}

/* Tooltip shown on hover */
.cite-tooltip {
    position: absolute;
    z-index: 200;
    max-width: 340px;
    padding: 0.55rem 0.75rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 3px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.07);
    font-family: var(--font-sans);
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.5;
    pointer-events: auto;
}

.cite-tooltip em {
    font-style: italic;
}


/* ============================================================
   BIBLIOGRAPHY (inside .page-meta-footer #bibliography)
   ============================================================ */

/* Number badge preceding each entry */
.ref-num {
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-faint);
    margin-right: 0.4em;
    white-space: nowrap;
}

/* Each bibliography entry */
.csl-bib-body .csl-entry {
    font-size: 0.95rem;
    color: var(--text-muted);
    line-height: 1.6;
    margin-bottom: 0.6rem;
    padding-left: 1.6em;
    text-indent: -1.6em;
}

.csl-bib-body .csl-entry a {
    color: var(--text-faint);
    word-break: break-all;
}

.csl-bib-body .csl-entry a:hover {
    color: var(--text-muted);
}


/* ============================================================
   COLLAPSIBLE SECTIONS
   collapse.js wraps h2/h3 content in .section-body divs and
   injects .section-toggle buttons into the heading elements.
   ============================================================ */

.section-body {
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.section-toggle {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-faint);
    padding: 0 0 0 0.5em;
    font-size: 0.5em;
    line-height: 1;
    vertical-align: middle;
    position: relative;
    top: -0.1em;
    opacity: 0;
    transition: color var(--transition-fast), opacity var(--transition-fast);
}

h2:hover .section-toggle,
h3:hover .section-toggle,
.section-toggle:hover,
.section-toggle:focus {
    opacity: 1;
}

.section-toggle:hover {
    color: var(--text-muted);
}

.section-toggle::before {
    content: '▼';
}

.section-toggle[aria-expanded="false"]::before {
    content: '▶';
}


/* ============================================================
   PAGEFIND SEARCH UI
   CSS custom property overrides so pagefind-ui matches the
   site's design tokens. Pagefind reads these via var().
   ============================================================ */

#search {
    margin-top: 1.65rem;
    --pagefind-ui-scale: 0.85;
    --pagefind-ui-primary: var(--text-muted);
    --pagefind-ui-text: var(--text);
    --pagefind-ui-background: var(--bg);
    --pagefind-ui-border: var(--border);
    --pagefind-ui-tag: var(--bg-offset);
    --pagefind-ui-border-width: 1px;
    --pagefind-ui-border-radius: 2px;
    --pagefind-ui-font: var(--font-sans);
}

#search-timing {
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    color: var(--text-faint);
    margin-top: 0.5rem;
    min-height: 1.2em; /* reserve space to prevent layout shift */
}

/* Search tabs (Keyword / Semantic toggle) */
.search-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 0.1rem;
    border-bottom: 1px solid var(--border);
}

.search-tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 0.45rem 1rem;
    font-family: var(--font-sans);
    font-size: var(--text-size-small);
    color: var(--text-faint);
    cursor: pointer;
    transition: color 0.1s, border-color 0.1s;
}

.search-tab:hover       { color: var(--text-muted); }
.search-tab.is-active   { color: var(--text); border-bottom-color: var(--text); }

/* Search panels (keyword / semantic) — only active panel visible */
.search-panel           { display: none; }
.search-panel.is-active { display: block; }

/* Semantic query input — mirrors Pagefind UI style */
.semantic-query-input {
    width: 100%;
    margin-top: 1.65rem;
    padding: 0.5rem 0.75rem;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 2px;
    box-sizing: border-box;
    outline: none;
}

.semantic-query-input:focus { border-color: var(--text-muted); }

.semantic-status {
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    color: var(--text-faint);
    margin-top: 0.5rem;
    min-height: 1.2em;
}

/* Semantic results list */
.semantic-results-list {
    list-style: none;
    margin: 1.2rem 0 0;
    padding: 0;
}

.semantic-result {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--border);
}

.semantic-result:last-child { border-bottom: none; }

.semantic-result-title {
    font-family: var(--font-sans);
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text);
    text-decoration: none;
}

.semantic-result-title:hover { text-decoration: underline; }

.semantic-result-heading {
    font-family: var(--font-sans);
    font-size: var(--text-size-small);
    color: var(--text-faint);
}

.semantic-result-excerpt {
    margin: 0.3rem 0 0;
    font-size: var(--text-size-small);
    color: var(--text-muted);
    line-height: 1.5;
}

/* ============================================================
   COMPOSITION LANDING PAGE
   ============================================================ */

.composition-meta .meta-row.composition-details {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.25rem;
    color: var(--text-muted);
    font-family: var(--font-ui);
    font-size: 0.85rem;
}

.comp-detail + .comp-detail::before {
    content: "·";
    margin-right: 1.25rem;
    color: var(--border);
}

.meta-row.composition-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.comp-btn {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    font-family: var(--font-ui);
    font-size: 0.82rem;
    font-weight: 600;
    border: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
    background: transparent;
    cursor: pointer;
}

.comp-btn:hover {
    background: var(--bg-offset);
}

.comp-btn--secondary {
    color: var(--text-muted);
}

/* Full-piece recording player */

.comp-recording {
    margin: 1.25rem 0;
}

.comp-recording-audio {
    width: 100%;
    height: 2rem;
    accent-color: var(--text-muted);
}

/* Movement list */

.composition-movements {
    margin: 1.25rem 0;
    border-top: 1px solid var(--border);
}

.comp-movement {
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--border);
}

.comp-movement-header {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.comp-movement-name {
    font-weight: 600;
    flex: 1 1 auto;
}

.comp-movement-duration {
    font-family: var(--font-ui);
    font-size: 0.82rem;
    color: var(--text-muted);
}

.comp-movement-score {
    font-family: var(--font-ui);
    font-size: 0.82rem;
    color: var(--text-muted);
    text-decoration: none;
}

.comp-movement-score:hover {
    text-decoration: underline;
}

.movement-audio {
    display: block;
    width: 100%;
    height: 2rem;
    margin-top: 0.5rem;
    accent-color: var(--text-muted);
}


/* ============================================================
   TRANSCLUSION
   States for <div class="transclude"> placeholders injected by
   Filters.Transclusion and populated by transclude.js.
   ============================================================ */

/* Loading placeholder — subtle pulse so the page doesn't look broken
   while the fetch is in flight. */
.transclude--loading {
    min-height: 1.65rem;
    background: var(--bg-offset);
    border-radius: 2px;
    animation: transclude-pulse 1.2s ease-in-out infinite;
}

@keyframes transclude-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.45; }
}

/* Loaded — transparent wrapper; content reads as native. */
.transclude--loaded {
    /* No visual treatment: transcluded content is visually native. */
}

/* Optional: uncomment to show a subtle left rule on loaded transclusions.
.transclude--loaded {
    border-left: 2px solid var(--border);
    padding-left: 1rem;
    margin-left: -1rem;
}
*/

/* Error state — faint inline notice. */
.transclude--error {
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    color: var(--text-faint);
    padding: 0.4rem 0;
}

/* Content wrapper — display:contents so the injected nodes participate
   in normal document flow without adding a structural block. */
.transclude--content {
    display: contents;
}

/* ============================================================
   COPY BUTTON
   Injected by copy.js into every <pre> block. Fades in on hover.
   ============================================================ */

.copy-btn {
    position: sticky;
    float: right;
    top: 0;
    right: 0;
    margin-top: -0.4rem;
    margin-right: -0.5rem;
    margin-bottom: -1.6em;
    font-family: var(--font-sans);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-faint);
    background: var(--bg);
    border: 1px solid var(--border-muted);
    border-radius: 3px;
    padding: 0.2em 0.55em;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s, color 0.15s, border-color 0.15s;
    user-select: none;
    line-height: 1.6;
    z-index: 1;
}

pre:hover .copy-btn,
.copy-btn:focus-visible {
    opacity: 1;
}

.copy-btn:hover {
    color: var(--text-muted);
    border-color: var(--border);
}

.copy-btn[data-copied] {
    color: var(--text-muted);
    border-color: var(--border);
    opacity: 1;
}

/* ============================================================
   TOUCH DEVICES
   (hover: none) and (pointer: coarse) reliably targets
   touchscreen-primary devices (phones, tablets) without
   relying on viewport width or user-agent sniffing.

   Goals:
     1. Suppress :hover states that "stick" after a tap
     2. Ensure tap targets meet ~44px minimum
     3. (popup disable is handled in popups.js)
   ============================================================ */

@media (hover: none) and (pointer: coarse) {
    /* Nav: ensure adequate vertical tap area even on wider tablets
       where the ≤540px query doesn't fire */
    .nav-primary a {
        padding-top: 0.35rem;
        padding-bottom: 0.35rem;
    }

    .nav-portal-toggle {
        padding-top: 0.3rem;
        padding-bottom: 0.3rem;
    }

    /* Settings gear: expand hit area without visual change */
    .settings-toggle {
        padding: 0.5rem;
        margin: -0.5rem;
    }

    /* Portal row links */
    .nav-portals a {
        padding-top: 0.3rem;
        padding-bottom: 0.3rem;
    }

    /* Suppress stuck hover states — reset to their non-hover values */
    .nav-primary a:hover           { color: var(--text-muted); }
    .nav-portals a:hover           { color: var(--text-faint); }
    .nav-portal-toggle:hover       { color: var(--text-faint); }
    .settings-toggle:hover         { color: var(--text-faint); }
    .toc-nav a:hover               { color: var(--text-faint); }
    .toc-nav > ol > li > a:hover   { color: var(--text-muted); }
    .hp-pro-row a:hover            { color: var(--text-muted); }
    .hp-curiosity-row a:hover      { color: var(--text-muted); }
    .hp-portal-name:hover          { text-decoration-color: var(--border-muted); }
    .meta-tag:hover                { color: var(--text-faint); }
    .backlink-source:hover         { color: var(--text-muted); }
    .section-toggle:hover          { color: var(--text-faint); }

    /* Copy button: always visible on touch (no persistent hover) */
    .copy-btn { opacity: 1; }
}

/* ============================================================
   PDF EMBED
   Inline PDF.js viewer iframes rendered from {{pdf:...}} directives.
   ============================================================ */

.pdf-embed-wrapper {
    margin: 1.5rem 0;
    border: 1px solid var(--border);
    border-radius: 2px;
    overflow: hidden;
    background: var(--bg-subtle);
}

.pdf-embed {
    display: block;
    width: 100%;
    height: 70vh;
    min-height: 420px;
    border: none;
}

@media (max-width: 600px) {
    .pdf-embed {
        height: 60vh;
        min-height: 300px;
    }
}

/* ── Archive affordance ─────────────────────────────────────────────────────
   The superscript "A" appended after a body link whose target is preserved
   in the local archive (build/Filters/Archive.hs). Loaded site-wide because
   the marker appears in essay/prose content, not on archive pages. */

.archive-affordance {
    font-size: 0.7em;
    margin-left: 0.15em;
    line-height: 0;
}

.archive-affordance a {
    font-family: var(--font-sans);
    font-weight: 600;
    text-decoration: none;
    color: var(--text-faint);
    border: 1px solid var(--border-muted);
    border-radius: 2px;
    padding: 0 0.25em;
}

.archive-affordance a:hover {
    color: var(--text);
    border-color: var(--text-muted);
    background: var(--bg-subtle);
}

/* Dead-link flip — a body link whose archived target is `rotted` has its
   href redirected to the local copy (build/Filters/Archive.hs). A dotted
   underline marks the link as redirected; its marker becomes a solid chip
   reading "archived" rather than the quiet bordered "A". */
.archive-rotted {
    text-decoration-style: dotted;
}

.archive-affordance--rotted a {
    color: var(--bg);
    background: var(--text-muted);
    border-color: var(--text-muted);
}

.archive-affordance--rotted a:hover {
    color: var(--bg);
    background: var(--text);
    border-color: var(--text);
}
