/*
 * Quarto Blog Theme — Academic/Minimal
 * Inspired by jamiesimon.io
 * Drop this file next to _quarto.yml
 */

/* ── Fonts ──────────────────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,600;1,400&family=Source+Code+Pro:wght@400;500&family=Inter:wght@400;500&display=swap');

/* ── Variables ──────────────────────────────────────────────── */
:root {
  --body-font:    'Lora', Georgia, serif;
  --ui-font:      'Inter', sans-serif;
  --code-font:    'Source Code Pro', monospace;

  --text-primary:   #1a1a1a;
  --text-secondary: #555;
  --text-muted:     #888;
  --accent:         #2a5db0;      /* a calm academic blue */
  --bg:             #FCF8F2;      /* slightly warm white */
  --border:         #e8e8e4;

  --content-width: 100%; /* let Quarto's grid control width */
  --side-pad: 1.5rem;
}

/* ── Base ───────────────────────────────────────────────────── */
body {
  font-family:      var(--body-font);
  font-size:        1.05rem;
  line-height:      1.8;
  color:            var(--text-primary);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
}

/* ── Layout: constrain content width ───────────────────────── */
.quarto-container,
#quarto-content,
.page-columns .column-body {
  max-width: var(--content-width) !important;
  margin: 0 auto;
  padding: 0 var(--side-pad);
}

/* full-width for listing pages (post grid) */
.quarto-listing {
  max-width: 860px;
  margin: 0 auto;
}

/* ── Navbar ─────────────────────────────────────────────────── */
.navbar {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border);
  padding: 0.75rem var(--side-pad);
}

.navbar-brand {
  font-family: var(--ui-font);
  font-weight: 500;
  font-size: 1rem;
  color: var(--text-primary) !important;
  letter-spacing: 0.01em;
}

.navbar-nav .nav-link {
  font-family: var(--ui-font);
  font-size: 0.875rem;
  color: var(--text-secondary) !important;
  transition: color 0.15s;
}

.navbar-nav .nav-link:hover {
  color: var(--text-primary) !important;
}

/* ── Post header ─────────────────────────────────────────────── */
.quarto-title h1.title {
  font-family: var(--body-font);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
  letter-spacing: -0.01em;
}

.quarto-title .description {
  font-family: var(--ui-font);
  font-size: 1rem;
  color: var(--text-secondary);
  margin-top: 0.25rem;
  font-style: normal;
}

.quarto-title-meta {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 1rem;
}

/* Estimated reading time, injected into the post header after every render by
   update_reading_time.sh. Sits just beneath the title-meta / date. */
.reading-time {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: -0.5rem;
  margin-bottom: 1.75rem;
}

/* Series membership, injected into the post header by
   filters/series_banner.lua. Sits above the reading time: the reading time is
   written after rendering, and tools/reading_time/patch.py steps over this
   banner so it stays on top. The adjacent-sibling rule below depends on it. */
.series-banner {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: -0.5rem;
  margin-bottom: 0.35rem;
}

.series-banner a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.series-banner a:hover {
  border-bottom-color: var(--accent);
}

/* The reading time keeps its negative top margin only when it is the first
   line under the title meta; the banner takes that role when present. */
.series-banner + .reading-time {
  margin-top: 0;
}

/* Previous/next links at the end of a series post, injected by
   scripts/inject_series_nav.py. Every rule here is a flat class selector on
   purpose: the block lands above the signup form on a public post but as a
   direct child of <main> when there is no form, so a descendant combinator
   would style only one of the two placements. */
.series-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 3rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--border);
  font-family: var(--ui-font);
  font-size: 0.8rem;
}

/* margin-left rather than justify-content: space-between, which would park a
   lone "Next" on the left of the first post in a series. */
.series-nav-next {
  margin-left: auto;
}

.series-nav-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.series-nav-link:hover {
  border-bottom-color: var(--accent);
}

/* ── Body text ───────────────────────────────────────────────── */
p {
  margin-bottom: 1.3rem;
}

h1, h2, h3, h4 {
  font-family: var(--body-font);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
}

h2 { font-size: 1.45rem; border-bottom: 1px solid var(--border); padding-bottom: 0.3rem; }
h3 { font-size: 1.2rem; }
h4 { font-size: 1rem; color: var(--text-secondary); }

a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s;
}

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

/* ── Math ────────────────────────────────────────────────────── */
/* Give display math room to breathe */
.math.display {
  overflow-x: auto;
  margin: 2rem 0;
  padding: 0.5rem 0;
}

/* ── Code ────────────────────────────────────────────────────── */
pre {
  font-family: var(--code-font);
  font-size: 0.85rem;
  line-height: 1.6;
  background: #f4f4f1;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1.1rem 1.25rem;
  overflow-x: auto;
  margin: 1.5rem 0;
}

code {
  font-family: var(--code-font);
  font-size: 0.85em;
  background: #f0f0ec;
  padding: 0.15em 0.35em;
  border-radius: 3px;
}

pre code {
  background: none;
  padding: 0;
  font-size: inherit;
}

/* code-fold button */
.code-fold-btn-row button {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ── Figures & images ────────────────────────────────────────── */
figure {
  margin: 2rem 0;
  text-align: center;
}

figure img {
  max-width: 100%;
  border-radius: 3px;
}

figcaption {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 0.5rem;
}

/* ── Blockquote ──────────────────────────────────────────────── */
blockquote {
  border-left: 3px solid var(--border);
  padding-left: 1.25rem;
  margin: 1.5rem 0;
  color: var(--text-secondary);
  font-style: italic;
}

/* ── Literature quote block ─────────────────────────────────── */
/* Rendered from a [!moviequote]/[!bookquote]/[!poemquote]/[!songquote]
   Obsidian callout by tools/qmd_lint/rules/lit_quote_rules.py (Q1). One
   shared block for any quoted line worth remembering, whatever it came from
   — the kind badge is the only thing that varies. Deliberately not one of
   Quarto's five native callout types — a note/tip/warning is de-emphasized
   admonition chrome, and a remembered line is the opposite of that, so it
   gets its own card look instead. The kind badge reuses the same small
   bordered-uppercase-pill look as .listing-pinned-badge elsewhere on the
   site, rather than inventing a second badge style. */
.lit-quote {
  margin: 2rem 0;
  padding: 1.5rem 1.75rem;
  background: #f6f2ea;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.lit-quote-meta {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-family: var(--ui-font);
  margin-bottom: 0.75rem;
}

.lit-quote-kind {
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
}

.lit-quote-source {
  flex: 1;
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
}

.lit-quote-date {
  font-size: 0.78rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.lit-quote blockquote {
  margin: 0;
  padding: 0;
  border-left: none;
  font-family: var(--body-font);
  font-size: 1.2rem;
  line-height: 1.6;
  font-style: italic;
  color: var(--text-primary);
}

.lit-quote blockquote p:last-child {
  margin-bottom: 0;
}

/* ── Tables ──────────────────────────────────────────────────── */
/* filters/table_scroll.lua wraps every table in this div. The scroll rule
   has to live on the wrapper rather than on `table` itself: the table's own
   `overflow: hidden` below clips its rounded corners, and that shorthand
   would stomp `overflow-x: auto`. Mirrors the pre/.math.display pattern —
   wide content scrolls instead of overflowing into #TOC. */
.table-scroll {
  overflow-x: auto;
  margin: 1.5rem 0;
}

#quarto-document-content table {
  border: 1px solid var(--bs-table-border-color, var(--border));
  border-collapse: separate;
  border-spacing: 0;
  border-radius: 4px;
  overflow: hidden;
}

.table-scroll table {
  margin: 0;
}

#quarto-document-content table > :last-child > tr:last-child > * {
  border-bottom-width: 0;
}

/* ── Table of Contents ───────────────────────────────────────── */
#TOC {
  font-family: var(--ui-font);
  font-size: 0.82rem;
  line-height: 1.6;
  overflow-wrap: break-word;
  word-wrap: break-word;
  hyphens: auto;
}

#TOC a {
  color: var(--text-secondary);
  border-bottom: none;
}

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

/* ── Listing page (index) ────────────────────────────────────── */
.quarto-listing-default .quarto-post {
  border-bottom: 1px solid var(--border);
  padding: 1.5rem 0;
}

.quarto-listing-default .quarto-post .thumbnail {
  display: none; /* clean text-only listing */
}

.quarto-listing-default .listing-title a {
  font-family: var(--body-font);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-primary);
  border-bottom: none;
}

.quarto-listing-default .listing-title a:hover {
  color: var(--accent);
}

.quarto-listing-default .listing-description {
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin-top: 0.25rem;
}

/* Pinned marker, injected by scripts/inject_pin_badges.py. Visible text rather
   than an icon, so it carries meaning without relying on colour or shape.
   Styled to match the muted, uncoloured look of .listing-category (the
   Quarto-default category tag) rather than standing out as an accent-coloured
   UI element. */
.quarto-listing-default .listing-pinned-badge {
  display: inline-block;
  font-family: var(--ui-font);
  font-size: 0.68rem;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
  margin-bottom: 0.4rem;
}

/* Series membership on a listing card, injected by
   scripts/inject_listing_badges.py. Deliberately quieter than the Pinned
   badge: it is context, not emphasis. A card carrying both stacks them, badge
   first. Never appears on a series landing page, where every card would
   repeat it. */
.quarto-listing-default .listing-series-label {
  font-family: var(--ui-font);
  font-size: 0.72rem;
  line-height: 1.4;
  margin-bottom: 0.35rem;
}

.quarto-listing-default .listing-series-label a {
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
}

.quarto-listing-default .listing-series-label a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.quarto-listing-default .listing-pinned-badge + .listing-series-label {
  margin-top: 0.1rem;
}

/* A homepage card standing in for a whole series, built by
   scripts/collapse_series_cards.py when _series_grouping.yml turns grouping
   on. It reuses Quarto's own card markup, so the only additions are the marker
   that tells a reader this row is a series rather than a post, and the post
   count that replaces the reading time in the metadata column. */
.quarto-listing-default .series-card-badge {
  display: inline-block;
  font-family: var(--ui-font);
  font-size: 0.68rem;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.1rem 0.4rem;
  margin-bottom: 0.4rem;
}

.quarto-listing-default .listing-post-count {
  font-family: var(--ui-font);
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* Explicit empty state for a series landing page with no published members.
   The post-render injector adds this only to the `series-posts` listing. */
.series-empty-state {
  font-family: var(--ui-font);
  font-size: 0.9rem;
  color: var(--text-muted);
  margin: 0.75rem 0 1.5rem;
}

.quarto-listing-default .listing-date {
  font-family: var(--ui-font);
  font-size: 0.78rem;
  color: var(--text-muted);
}

.quarto-listing-default .listing-reading-time {
  font-family: var(--ui-font);
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* Categories filter sidebar, as a single thin-outlined box (not a per-item
   box — that would compete with the bordered-pill tags used by
   .listing-category / .listing-pinned-badge / .quarto-category elsewhere on
   the page). align-self: start keeps the box sized to its own content —
   without it, the grid's default `align-items: stretch` pads
   #quarto-margin-sidebar out to the height of the whole listing column, so
   the outline reads as a giant slab instead of hugging the category list
   (and growing/shrinking with it as categories are added or removed).
   Scoped with :has() rather than styling #quarto-margin-sidebar directly,
   since that same container id also holds #TOC on post pages, which should
   stay a plain list. */
#quarto-margin-sidebar:has(.quarto-listing-category-title) {
  align-self: start;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1rem 1.25rem;
}

#quarto-margin-sidebar .quarto-listing-category-title {
  font-family: var(--ui-font);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.4rem;
  margin-bottom: 0.5rem;
}

#quarto-margin-sidebar .quarto-listing-category .category {
  font-family: var(--ui-font);
  font-size: 0.85rem;
  color: var(--text-secondary);
  margin-bottom: 0.5rem;
}

#quarto-margin-sidebar .quarto-listing-category .category:last-child {
  margin-bottom: 0;
}

#quarto-margin-sidebar .quarto-listing-category .category:hover {
  color: var(--accent);
}

#quarto-margin-sidebar .quarto-listing-category .category.active {
  color: var(--accent);
  font-weight: 600;
}

#quarto-margin-sidebar .quarto-category-count {
  color: var(--text-muted);
  font-weight: 400;
}

/* Subscribe jump-link, appended inside the categories box by
   scripts/inject_subscribe_link.py. The homepage form sits below every listing
   card, so this is what makes it reachable without scrolling the whole page.
   Filled in the accent, matching the form's own button, because a quiet link
   here would repeat the mistake the form's first styling made. Separated from
   the category list by a rule so it reads as a control rather than a sixth
   category. */
.subscribe-sidebar-link {
  display: block;
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.subscribe-sidebar-link a {
  display: block;
  font-family: var(--ui-font);
  font-size: 0.85rem;
  font-weight: 500;
  text-align: center;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 0.45rem 0.6rem;
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s;
}

.subscribe-sidebar-link a:hover,
.subscribe-sidebar-link a:focus-visible {
  background: #24509a;
  border-color: #24509a;
  color: #fff;
}

/* Mobile counterpart to the sidebar jump-link above, inserted at the top of
   the homepage body by filters/subscribe.lua.

   767.98px is not a round number picked for looks: it is the exact width at
   which Quarto's own bootstrap bundle applies

       @media(max-width: 767.98px){ ... #quarto-margin-sidebar{display:none} }

   Below that the sidebar button does not exist on screen, so this line is the
   only thing standing between a phone reader and scrolling past every listing
   card to discover the form. Above it the sidebar button is showing and this
   would be a duplicate, so it is hidden by default and revealed only inside
   the query. Changing either number without the other leaves a band of widths
   showing both entry points or neither -- tests/test_subscribe_link.py pins
   them together.

   Deliberately a line of text, not a bordered panel: a second box here would
   lead the page with a signup box on the narrowest screens, which is the exact
   thing moving the form to the bottom was meant to stop. */
.subscribe-mobile-link {
  display: none;
  margin: 0 0 1.5rem;
  font-family: var(--ui-font);
  font-size: 0.9rem;
}

.subscribe-mobile-link a {
  color: var(--accent);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid rgba(42, 93, 176, 0.35);
  padding-bottom: 1px;
}

.subscribe-mobile-link a:hover,
.subscribe-mobile-link a:focus-visible {
  border-bottom-color: var(--accent);
}

@media (max-width: 767.98px) {
  .subscribe-mobile-link {
    display: block;
  }
}

/* ── Footer ──────────────────────────────────────────────────── */
.nav-footer {
  font-family: var(--ui-font);
  font-size: 0.8rem;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
}

/* ── Bibliography / citations ────────────────────────────────── */
#refs {
  font-family: var(--ui-font);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* Applied globally so the citation hover popup (rendered outside #refs) also picks this up. */
div.csl-entry {
  margin-bottom: 0.4rem;
}

div.csl-left-margin,
div.csl-right-inline {
  display: inline;
  float: none;
  min-width: 0;
  margin: 0;
  padding: 0;
}

/* ── Download PDF button ─────────────────────────────────────── */
/* Injected into the post title block by scripts/build_post_pdfs.py, which adds
   it only for a post whose PDF was actually written. Absolutely positioned so
   it sits top-right of the header regardless of how tall the title, the
   categories and the description below it turn out to be. */
#title-block-header {
  position: relative;
}

/* Reserve the corner so a long title wraps before it reaches the button
   instead of running underneath it. */
#title-block-header > .quarto-title {
  padding-right: 3rem;
}

.post-pdf-download {
  position: absolute;
  top: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--ui-font);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--text-secondary);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.35rem;
  transition: color 0.15s, border-color 0.15s;
}

.post-pdf-download:hover,
.post-pdf-download:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

.post-pdf-download-icon {
  flex: none;
}

.post-pdf-download-label {
  display: none;
}

/* ── Interactive embeds ──────────────────────────────────────── */
/* Emitted after each iframe by filters/interactive_embed.lua. On screen the
   embed is all there is; the note exists only for the printed page. */
.interactive-embed-note {
  display: none;
}

/* ── Email signup ────────────────────────────────────────────── */
/* Inserted by filters/subscribe.lua: at the end of the body on a post (above
   the comments), at the top of the homepage.

   An earlier version was a bare top rule with a caption-sized label and an
   outline button. It matched the page so well that readers scrolled past it --
   the control read as a footnote rather than as something to act on. This is
   the correction: a tinted panel to separate it from the prose, a label at
   heading weight, and one filled button so the action is unambiguous. The tint
   and the accent are the site's existing values, so it is louder without being
   foreign. */
.subscribe-form {
  margin: 3.5rem 0 0;
  padding: 1.6rem 1.75rem;
  background: #F6F0E6;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--ui-font);
  /* The sidebar link jumps here; without this the form lands under the fixed
     navbar. */
  scroll-margin-top: 5rem;
}

.subscribe-form-label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* Answers the two questions a reader has before typing an address. */
.subscribe-form-note {
  margin: 0 0 1rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.subscribe-form-row {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
  max-width: 26rem;
}

/* White against the panel tint, so the field reads as somewhere to type. */
.subscribe-form-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--ui-font);
  font-size: 0.9rem;
  color: var(--text-primary);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.5rem 0.7rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.subscribe-form-input::placeholder {
  color: var(--text-muted);
}

/* Replaces the suppressed outline rather than removing the focus cue. */
.subscribe-form-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(42, 93, 176, 0.15);
}

/* Filled, not outlined. The outline version sat at the same visual weight as
   the input beside it and read as a secondary control. */
.subscribe-form-button {
  flex: none;
  font-family: var(--ui-font);
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 0.5rem 1.2rem;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}

.subscribe-form-button:hover,
.subscribe-form-button:focus-visible {
  background: #24509a;
  border-color: #24509a;
}

.subscribe-form-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 768px) {
  :root { --content-width: 100%; }
  body  { font-size: 1rem; }
  .quarto-title h1.title { font-size: 1.6rem; }

  /* Too little width left for a title beside the button, so return it to the
     flow. It is the header's first child, so it lands above the title. */
  #title-block-header > .quarto-title { padding-right: 0; }
  .post-pdf-download {
    position: static;
    margin-bottom: 1rem;
    padding: 0.35rem 0.7rem;
  }

  .post-pdf-download-label {
    display: inline;
  }

  /* Side by side there is not enough width left for a usable email field, so
     the button drops below it and both go full width. */
  .subscribe-form-row {
    flex-direction: column;
    max-width: none;
  }
}

/* ── Print / PDF export ──────────────────────────────────────── */
/* This block is what the downloadable PDF looks like: the button prints the
   page through headless Chrome, so every rule here lands in the file readers
   get. Kept last in the file so it wins the cascade over the screen rules it
   overrides. */
@page {
  margin: 18mm 16mm;
}

@media print {
  /* Site chrome, navigation and anything interactive: all meaningless on
     paper, and the download button least meaningful of all inside the very
     document it downloads. */
  .navbar,
  #quarto-sidebar,
  #quarto-margin-sidebar,
  #TOC,
  nav[role="doc-toc"],
  .nav-footer,
  #quarto-back-to-top,
  .giscus,
  #giscus-container,
  .quarto-comments,
  .post-pdf-download,
  .series-nav,
  .subscribe-form {
    display: none !important;
  }

  /* With both sidebars gone, Quarto's grid would leave their columns behind as
     empty space. Collapsing to a single flow lets the body use the full page.

     The :not() chain is not defensive tidiness — it is load-bearing. Quarto
     emits <script id="quarto-html-after-body"> as a *direct child* of
     #quarto-content, which is the element carrying .page-columns. Without the
     exclusions, `display: block !important` overrides the browser's default
     `display: none` for that script and its entire source prints as body copy:
     several pages of minified JavaScript at the end of every PDF. It cannot be
     undone by a later `script { display: none !important }` either, because
     both rules would be !important and this selector is the more specific one.
     The exclusion has to live here. */
  .page-columns,
  .page-columns > *:not(script):not(style):not(link):not(meta):not(template):not(noscript) {
    display: block !important;
  }

  body,
  #quarto-content,
  #quarto-document-content,
  .content,
  .quarto-container {
    max-width: none !important;
    width: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    background: #fff !important;
  }

  body {
    font-size: 10.5pt;
    line-height: 1.55;
  }

  /* Underlined blue links read as noise in print, but the citation and
     bibliography links are load-bearing cross-references, so they keep their
     colour. */
  a {
    color: inherit;
    text-decoration: none;
  }

  #refs a,
  a.citation,
  sup a {
    color: var(--accent);
  }

  /* An iframe prints as a dead rectangle at best. Swap it for the note that
     says what was there — see filters/interactive_embed.lua. */
  iframe {
    display: none !important;
  }

  .interactive-embed-note {
    display: block;
    font-family: var(--ui-font);
    font-size: 0.85em;
    font-style: italic;
    color: var(--text-secondary);
    border: 1px dashed var(--border);
    border-radius: 4px;
    padding: 0.75rem 1rem;
    overflow-wrap: anywhere;
  }

  /* Page-break hygiene: no heading stranded at the foot of a page, and no
     figure, table or equation split across one. */
  h1,
  h2,
  h3,
  h4 {
    break-after: avoid;
  }

  figure,
  table,
  pre,
  blockquote,
  .lit-quote,
  mjx-container {
    break-inside: avoid;
  }

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