diff --git a/static/css/print.css b/static/css/print.css
index 9d230d3..87f209f 100644
--- a/static/css/print.css
+++ b/static/css/print.css
@@ -1,5 +1,10 @@
/* print.css — Clean paper output.
- Loaded on every page via .
+ Loaded LAST in head.html via so its rules win
+ the cascade at print page widths (~595–820 CSS px on A4/Letter),
+ which otherwise trip every screen breakpoint below 900px (mobile
+ TOC bar, body bottom padding) and below 1499px (sidenote → footnote
+ fallback).
+
Hides chrome, expands body full-width, renders in black on white. */
@media print {
@@ -13,7 +18,8 @@
[data-theme="dark"],
[data-theme="cappuccino"] {
--bg: #ffffff;
- --bg-offset: #f5f5f5;
+ --bg-nav: #ffffff;
+ --bg-offset: #ffffff;
--bg-subtle: #f9f9f9;
--text: #000000;
--text-muted: #333333;
@@ -23,36 +29,71 @@
--rule: #cccccc;
}
+ /* Reading-mode body warm tints would otherwise repaint pages cream. */
+ body.reading-mode { --bg: #ffffff; }
+
/* ----------------------------------------------------------------
- Hide chrome entirely
+ Hide chrome.
+
+ Site nav is `body > header` (templates/partials/nav.html); the
+ essay frontmatter is `.page-shell > header.essay-frontmatter`
+ (essay/blog-post/reading templates) and MUST stay visible — its
+
is the page title.
+
+ The mark slots (monogram + epistemic figure) and frontmatter
+ divider are decorative; suppressing them lets the title block
+ collapse to a clean masthead.
---------------------------------------------------------------- */
- header,
- footer,
+ body > header,
+ .page-shell > footer,
#toc,
+ #toc-mobile-bar,
+ #reading-progress,
+ .skip-link,
.settings-wrap,
.selection-popup,
.link-popup,
+ .ann-tooltip,
+ .ann-picker,
+ .sidenote-popup-overlay,
.toc-toggle,
.section-toggle,
+ .nav-portals,
+ .nav-portal-toggle,
+ .footer-ornament,
+ .content-divider,
+ .aftermatter-divider,
+ .frontmatter-mark-slot,
.metadata .meta-pagelinks,
.page-meta-footer #backlinks,
.page-meta-footer #similar-links,
- .nav-portals {
+ .version-history-more {
display: none !important;
}
+ /* The mobile TOC bar's screen rule also adds `body { padding-bottom: 2.5rem }`
+ to clear the fixed strip — undo it on paper. */
+ body {
+ padding-bottom: 0 !important;
+ }
+
/* ----------------------------------------------------------------
Layout — single full-width column
---------------------------------------------------------------- */
body {
font-size: 11pt;
- line-height: 1.6;
+ line-height: 1.55;
background: var(--bg);
color: var(--text);
margin: 0;
padding: 0;
}
+ .page-shell {
+ display: block !important;
+ min-height: 0 !important;
+ }
+
#content {
display: block !important;
width: 100% !important;
@@ -60,7 +101,11 @@
margin: 0 !important;
}
- #markdownBody {
+ #markdownBody,
+ .page-shell > #markdownBody,
+ body.reading-mode .page-shell > #markdownBody,
+ body.reading-mode.poetry > #markdownBody,
+ body.reading-mode.fiction > #markdownBody {
width: 100% !important;
max-width: 100% !important;
grid-column: unset !important;
@@ -68,29 +113,157 @@
padding: 0 !important;
}
- /* Sidenotes: pull inline as footnote-like blocks */
- .sidenote-ref {
- display: none;
+ /* ----------------------------------------------------------------
+ Essay frontmatter — collapse the 3-column viewport-spanning grid
+ to a single linear masthead. Mark slots already hidden above.
+ ---------------------------------------------------------------- */
+ .essay-frontmatter {
+ display: block !important;
+ padding: 0 0 0.6em 0 !important;
+ margin: 0 0 1em 0 !important;
+ border-bottom: 1px solid var(--border);
}
+
+ .frontmatter-title {
+ max-width: 100% !important;
+ width: 100% !important;
+ text-align: left !important;
+ justify-self: stretch !important;
+ }
+
+ .frontmatter-title > .page-title {
+ font-size: 22pt;
+ margin: 0 0 0.2em 0;
+ line-height: 1.15;
+ }
+
+ .essay-subtitle {
+ font-size: 12pt;
+ margin: 0 0 0.4em 0;
+ }
+
+ .frontmatter-title .meta-description {
+ text-align: left !important;
+ }
+
+ .frontmatter-title .meta-epistemic-strip {
+ justify-content: flex-start !important;
+ }
+
+ .essay-tailmatter {
+ max-width: 100% !important;
+ width: 100% !important;
+ padding: 0 !important;
+ margin: 0 0 1em 0 !important;
+ }
+
+ .essay-summary {
+ background: transparent !important;
+ border: 1px solid var(--border-muted);
+ padding: 0.6em 0.8em !important;
+ margin: 0.5em 0 1em 0 !important;
+ }
+
+ /* ----------------------------------------------------------------
+ Sidenotes — render inline as parenthetical asides.
+
+ The build's Sidenotes filter replaces Pandoc's
+ `section.footnotes` entirely with ``
+ siblings of the ref, so there is no end-of-document footnote
+ section to fall back to. Sidenotes.css hides .sidenote at
+ narrow widths (which print triggers); print.css promotes them
+ back inline as small italic parentheticals so the surrounding
+ sentence flow stays intact — block-style footnotes mid-sentence
+ leave dangling clauses on the next line.
+ ---------------------------------------------------------------- */
.sidenote {
- display: block;
+ display: inline !important;
position: static !important;
width: auto !important;
- margin: 0.5em 2em;
- padding: 0.4em 0.8em;
- border-left: 2px solid var(--border);
- font-size: 9pt;
+ max-width: none !important;
+ margin: 0;
+ padding: 0;
+ border: none;
+ font-size: 0.85em;
+ font-style: italic;
+ color: var(--text-muted);
+ }
+
+ .sidenote::before { content: " ["; font-style: normal; }
+ .sidenote::after { content: "]"; font-style: normal; }
+
+ .sidenote-para {
+ display: inline !important;
+ margin: 0 !important;
+ }
+ .sidenote-para + .sidenote-para::before {
+ content: " / ";
+ font-style: normal;
color: var(--text-faint);
}
+ .sidenote-num {
+ display: none !important;
+ }
+
+ .sidenote-ref a {
+ color: var(--text);
+ text-decoration: none;
+ }
+
+ /* ----------------------------------------------------------------
+ User annotations — strip on-screen highlight backgrounds; keep
+ a faint underline so the marker still surfaces on paper.
+ ---------------------------------------------------------------- */
+ mark.user-annotation {
+ background: transparent !important;
+ color: inherit !important;
+ padding: 0 !important;
+ text-decoration: underline;
+ text-decoration-color: var(--text-faint);
+ text-decoration-thickness: 0.5pt;
+ text-underline-offset: 0.18em;
+ }
+
+ /* ----------------------------------------------------------------
+ Figures — strip on-screen card chrome (bg-offset card, inner
+ image border, drop shadow). Plain image + caption reads more
+ naturally on paper.
+ ---------------------------------------------------------------- */
+ #markdownBody figure {
+ background: transparent !important;
+ border: none !important;
+ box-shadow: none !important;
+ padding: 0 !important;
+ margin: 1em auto !important;
+ max-width: 100% !important;
+ }
+
+ #markdownBody figure img {
+ border: none !important;
+ }
+
+ #markdownBody figcaption {
+ font-size: 9pt;
+ margin-top: 0.3em;
+ }
+
+ /* ----------------------------------------------------------------
+ Drop cap — quieten the magazine flourish; at 3.8em it prints as
+ a giant black blob that wastes the first half page.
+ ---------------------------------------------------------------- */
+ #markdownBody > p:first-of-type::first-letter,
+ #markdownBody .dropcap p::first-letter,
+ body.reading-mode.fiction > #markdownBody h2 + p::first-letter {
+ font-size: 2.4em;
+ line-height: 0.9;
+ }
+
/* ----------------------------------------------------------------
Page setup
---------------------------------------------------------------- */
@page {
- margin: 2cm 2.5cm;
- }
- @page :first {
- margin-top: 3cm;
+ margin: 2cm 2cm;
}
/* ----------------------------------------------------------------
@@ -106,41 +279,49 @@
widows: 3;
}
- pre, figure, .exhibit {
+ pre, figure, .exhibit, table {
page-break-inside: avoid;
break-inside: avoid;
}
- /* Show href after external links */
- a[href^="http"]::after {
- content: " (" attr(href) ")";
- font-size: 0.8em;
- color: var(--text-faint);
- word-break: break-all;
- }
- /* But not for nav or obvious UI links */
- .cite-link::after,
- .meta-tag::after,
- a[href^="#"]::after {
+ /* Decorative inline link-icon glyphs (wikipedia W, arxiv X, github,
+ etc.) — they render as an inline-block 0.75em × 0.75em masked
+ SVG, fine on screen but on paper they print as an opaque black
+ speckle next to every external link. Suppress them entirely.
+ Critical: this also unsets the fixed width/height/mask so any
+ `::after` content from another rule renders as plain inline text. */
+ a[data-link-icon-type="svg"]::after,
+ a[data-link-icon]::after {
content: none !important;
+ display: none !important;
}
+ /* External links keep their default underline — readers can follow
+ the live URL via the PDF's preserved link metadata. We don't
+ inline the href as printed text because (a) it duplicates the
+ link, (b) `word-break: break-all` URLs interact badly with the
+ link-icon ::after we just suppressed, and (c) it makes the page
+ visually noisy. */
+
/* ----------------------------------------------------------------
Code blocks — strip background, border only
---------------------------------------------------------------- */
pre, code {
- background: var(--bg-subtle) !important;
+ background: transparent !important;
border: 1px solid var(--border-muted) !important;
box-shadow: none !important;
}
/* ----------------------------------------------------------------
- Bibliography / footer — keep but compact
+ Page meta footer — keep epistemic + version history compact;
+ collapse the auto-fit grid so columns don't get pushed onto a
+ new page when the body ended near a break.
---------------------------------------------------------------- */
.page-meta-footer {
margin-top: 1.5em;
- padding-top: 1em;
+ padding: 1em 0 0 0 !important;
border-top: 1px solid var(--border);
+ gap: 0.8em !important;
}
.meta-footer-full,
@@ -148,4 +329,12 @@
width: 100% !important;
max-width: 100% !important;
}
+
+ .meta-footer-grid {
+ display: block !important;
+ }
+
+ .meta-footer-section {
+ margin-bottom: 0.8em;
+ }
}