/* =========================================================================
   Variant 01 — Swiss Modernism 2.0   (styles.csv #50)
   Grid system · Inter · mathematical spacing · asymmetric balance
   Single vibrant accent. No gradients. No shadows. No radius.
   ========================================================================= */

@import url('fonts/fonts.css');

:root {
  --ink:    #000000;
  --paper:  #FFFFFF;
  --grey:   #F5F5F5;
  --rule:   #000000;
  --muted:  #595959;
  /* The one vibrant note, per spec. Darkened from #E8442A, which measured
     3.97:1 on white — the database claims WCAG AAA for this style, so the
     accent has to actually clear AA at small sizes. This lands at 4.84. */
  --accent: #D13A1E;

  --unit: 8px;                /* every measurement is a multiple of this */
  --gap: calc(var(--unit) * 3);
  --cols: 12;

  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink:   #FFFFFF;
    --paper: #000000;
    --grey:  #141414;
    --rule:  #FFFFFF;
    --muted: #A6A6A6;
    --accent:#FF6A50;
  }
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  font-feature-settings: 'tnum' 1, 'cv05' 1;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.035em; line-height: 0.98; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--accent); }
a:hover { color: var(--accent); }

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

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; }
}

/* ---- The grid ----------------------------------------------------------
   One 12-column grid governs the whole page. Every element is placed by
   column number — nothing is centred, nothing is "auto". That placement is
   what makes this read as designed rather than defaulted.
   ---------------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  gap: 0 var(--gap);
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: calc(var(--unit) * 4);
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ink); color: var(--paper);
  padding: var(--unit) calc(var(--unit) * 2);
  font-size: 13px; font-weight: 600; border: 0;
}
.skip:focus { left: 0; }

/* ---- Masthead ---------------------------------------------------------- */

.masthead {
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
}
.masthead .grid { align-items: center; min-height: calc(var(--unit) * 7); }

.masthead-name {
  grid-column: 1 / 4;
  font-size: 15px; font-weight: 600; letter-spacing: -0.02em;
  border: 0;
}
.masthead-nav {
  grid-column: 8 / -1;
  display: flex; justify-content: flex-end; gap: calc(var(--unit) * 4);
  font-size: 12px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
}
.masthead-nav a { border: 0; color: var(--muted); }
.masthead-nav a:hover, .masthead-nav a[aria-current="page"] { color: var(--ink); }

/* ---- Section scaffold --------------------------------------------------
   Marker in columns 1–2, content from 4. The wide empty gutter is the
   whole idea: asymmetry, not centring.
   ---------------------------------------------------------------------- */

.section { border-bottom: 1px solid var(--rule); padding-block: calc(var(--unit) * 9); }

.marker {
  grid-column: 1 / 3;
  font-size: 12px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent);
  align-self: start;
}
.marker span { display: block; color: var(--muted); font-weight: 400; margin-top: var(--unit); }

.body-col   { grid-column: 4 / 10; }
.body-wide  { grid-column: 4 / -1; }

@media (max-width: 900px) {
  .marker, .body-col, .body-wide, .masthead-name, .masthead-nav { grid-column: 1 / -1; }
  .marker { margin-bottom: calc(var(--unit) * 2); }
  .masthead-nav { justify-content: flex-start; }
  .masthead .grid { padding-block: calc(var(--unit) * 1.5); row-gap: var(--unit); }
}

/* ---- Hero -------------------------------------------------------------- */

.hero { padding-block: calc(var(--unit) * 6) calc(var(--unit) * 5); border-bottom: 1px solid var(--rule); }

/* Identity row. The name is centred over the lede column (1–6); the portrait is
   centred over the blurb column (9–12). Both sit on the same row because their
   column ranges don't overlap, and align-self keeps them on one horizontal line. */
.hero h1 {
  grid-column: 1 / 7;
  justify-self: center;
  align-self: center;
  text-align: center;
  font-size: clamp(2.5rem, 6.5vw, 5.5rem);
  margin: 0 0 calc(var(--unit) * 4);
}
.hero-portrait {
  grid-column: 9 / -1;
  justify-self: center;
  align-self: center;
  width: clamp(112px, 12vw, 176px);
  height: clamp(112px, 12vw, 176px);
  border-radius: 50%;
  object-fit: cover;
  margin: 0 0 calc(var(--unit) * 4);
}

.hero-lede {
  grid-column: 1 / 7;
  font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
  line-height: 1.4;
  letter-spacing: -0.01em;
}
.hero-sub {
  grid-column: 9 / -1;
  font-size: 14px; line-height: 1.55; color: var(--muted);
  border-top: 1px solid var(--rule); padding-top: calc(var(--unit) * 2);
}

@media (max-width: 900px) {
  .hero h1, .hero-portrait, .hero-lede, .hero-sub { grid-column: 1 / -1; }
  .hero-portrait { order: -1; margin-bottom: calc(var(--unit) * 3); }
  .hero h1 { margin-bottom: calc(var(--unit) * 3); }
  .hero-sub { margin-top: calc(var(--unit) * 3); }
}

/* ---- Credentials — a data row, not cards ------------------------------- */

.creds { border-bottom: 1px solid var(--rule); padding-block: calc(var(--unit) * 4); }
.creds dl { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); margin: 0; }
.creds dt {
  font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--unit);
}
.creds dd {
  margin: 0;
  font-size: clamp(1.25rem, 2.6vw, 2rem); font-weight: 600; letter-spacing: -0.03em;
  line-height: 1;
}
.creds dd small { display: block; font-size: 12px; font-weight: 400; letter-spacing: 0; color: var(--muted); margin-top: var(--unit); }
@media (max-width: 700px) { .creds dl { grid-template-columns: repeat(2, 1fr); row-gap: calc(var(--unit) * 3); } }

/* ---- Prose ------------------------------------------------------------- */

.prose { font-size: 1rem; line-height: 1.6; max-width: 62ch; }
.prose--lead { font-size: 1.125rem; }

/* Headings carry .prose directly on the element in the markup, so they must be
   matched as h2.prose — a descendant selector (.prose h2) never fires and the
   heading silently inherits body size. */
.prose h2, h2.prose {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: 600;
  line-height: .98;
  letter-spacing: -0.035em;
  margin-bottom: calc(var(--unit) * 3);
  max-width: 22ch;
}
.prose h3 { font-size: 1.125rem; margin: calc(var(--unit) * 5) 0 var(--unit); letter-spacing: -0.02em; }
.prose em { font-style: italic; }

/* ---- Index list (writing) — numbered, ruled, no cards ------------------ */

.index-list { grid-column: 1 / -1; list-style: none; margin: 0; padding: 0; }
.index-list li { border-top: 1px solid var(--rule); }
.index-list li:last-child { border-bottom: 1px solid var(--rule); }

.index-row {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  gap: 0 var(--gap);
  padding-block: calc(var(--unit) * 3);
  align-items: baseline;
  text-decoration: none; border: 0; color: inherit;
}
.index-row:hover { background: var(--grey); }
.index-row:hover .index-title { color: var(--accent); }

.index-num   { grid-column: 1 / 2; font-size: 12px; color: var(--accent); font-weight: 600; }
.index-title { grid-column: 2 / 7; font-size: clamp(1.125rem, 2vw, 1.5rem); font-weight: 600; letter-spacing: -0.025em; }
.index-desc  { grid-column: 7 / 11; font-size: 14px; color: var(--muted); line-height: 1.5; }
.index-meta  { grid-column: 11 / -1; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); text-align: right; }

@media (max-width: 900px) {
  .index-row { grid-template-columns: calc(var(--unit) * 4) 1fr; row-gap: var(--unit); }
  .index-num { grid-column: 1; }
  .index-title, .index-desc, .index-meta { grid-column: 2; text-align: left; }
}

/* ---- Publications ------------------------------------------------------ */

.pubs { grid-column: 1 / -1; list-style: none; margin: 0; padding: 0; counter-reset: pub; }
.pubs > li {
  border-top: 1px solid var(--rule);
  padding-block: calc(var(--unit) * 3);
  display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: 0 var(--gap);
}
.pubs > li:last-child { border-bottom: 1px solid var(--rule); }
.pub-idx { grid-column: 1 / 2; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.pub-main { grid-column: 2 / 9; }
.pub-side { grid-column: 9 / -1; font-size: 12px; color: var(--muted); line-height: 1.5; }
.pub-title { font-weight: 600; font-size: 15px; letter-spacing: -0.015em; display: block; margin-bottom: var(--unit); }
.pub-authors { font-size: 12px; color: var(--muted); line-height: 1.55; }
.pub-authors b { color: var(--ink); }
.pub-side em { font-style: normal; color: var(--ink); font-weight: 500; }
@media (max-width: 900px) {
  .pubs > li { grid-template-columns: calc(var(--unit) * 4) 1fr; row-gap: var(--unit); }
  .pub-idx { grid-column: 1; } .pub-main, .pub-side { grid-column: 2; }
}

.subhead {
  grid-column: 1 / -1;
  font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
  margin: calc(var(--unit) * 5) 0 var(--unit);
}
.subhead:first-of-type { margin-top: 0; }

/* ---- Essay page -------------------------------------------------------- */

.essay-head { padding-block: calc(var(--unit) * 10) calc(var(--unit) * 5); border-bottom: 1px solid var(--rule); }
.essay-kicker {
  grid-column: 1 / 3;
  font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
}
.essay-head h1 { grid-column: 4 / 11; font-size: clamp(2.5rem, 6.5vw, 5rem); margin-bottom: calc(var(--unit) * 3); }
.essay-standfirst { grid-column: 4 / 10; font-size: clamp(1.0625rem, 1.8vw, 1.3125rem); line-height: 1.4; color: var(--muted); letter-spacing: -0.01em; }
@media (max-width: 900px) { .essay-kicker, .essay-head h1, .essay-standfirst { grid-column: 1 / -1; } .essay-kicker { margin-bottom: calc(var(--unit)*2); } }

.pull {
  border-top: 2px solid var(--accent);
  border-bottom: 1px solid var(--rule);
  margin: calc(var(--unit) * 5) 0;
  padding: calc(var(--unit) * 3) 0;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 500; letter-spacing: -0.025em; line-height: 1.2;
  max-width: 30ch;
}

.footnote { font-size: 12px; color: var(--muted); line-height: 1.55; border-top: 1px solid var(--rule); padding-top: calc(var(--unit) * 2); margin-top: calc(var(--unit) * 6); }
.footnote a { border-bottom-color: var(--accent); }

/* ---- Outbound links to papers -----------------------------------------
   Publication titles link straight to the paper. The global rule puts an
   accent border under every link, which on a three-line title means three
   accent rules fighting the ruled grid — so these opt out and carry an arrow
   instead. The arrow is a non-colour cue, which is what WCAG 1.4.1 asks for,
   and it doubles as the "this leaves the site" signal since these open in a
   new tab. The underline arrives on hover and focus.
   ---------------------------------------------------------------------- */

.paper { border-bottom: 0; color: inherit; }
.paper:hover,
.paper:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ext {
  display: inline-block;
  margin-left: .35em;
  color: var(--accent);
  font-weight: 400;
  font-size: .8em;
  line-height: 1;
}

/* Available to assistive technology, never painted. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Colophon ---------------------------------------------------------- */

.colophon { padding-block: calc(var(--unit) * 5); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.colophon .left  { grid-column: 1 / 7; }
.colophon .right { grid-column: 9 / -1; text-align: right; }
@media (max-width: 900px) { .colophon .left, .colophon .right { grid-column: 1 / -1; text-align: left; } .colophon .right { margin-top: var(--unit); } }


/* =========================================================================
   Pages added when Swiss was built out: writing index, the two side-by-side
   translations, and the CV.
   ========================================================================= */

/* ---- Side-by-side comparison -------------------------------------------
   Swiss allows one accent and no decorative colour, so the two columns are
   distinguished by ground tone and rule weight rather than by hue: source on
   grey with a hairline, plain-English on paper under a heavy accent rule.
   ---------------------------------------------------------------------- */

.compare { grid-column: 4 / -1; }
@media (max-width: 900px) { .compare { grid-column: 1 / -1; } }

.compare-tabs { display: none; gap: 0; margin-bottom: calc(var(--unit) * 3); }
.compare[data-tabs="on"] .compare-tabs { display: flex; }
.compare-tabs button {
  flex: 1;
  font-family: var(--font); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); background: var(--paper);
  border: 1px solid var(--rule); border-right: 0;
  padding: calc(var(--unit) * 1.5) var(--unit);
  cursor: pointer; border-radius: 0;
}
.compare-tabs button:last-child { border-right: 1px solid var(--rule); }
.compare-tabs button[aria-selected="true"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
}

.compare-grid { display: grid; gap: var(--gap); }
@media (min-width: 60rem) { .compare-grid { grid-template-columns: 1fr 1fr; } }

.panel { padding: calc(var(--unit) * 3); border-radius: 0; }
.panel--source { background: var(--grey); border-top: 1px solid var(--rule); }
.panel--plain  { background: var(--paper); border-top: 2px solid var(--accent); }

.panel-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--unit);
  margin-bottom: calc(var(--unit) * 2);
  padding-bottom: var(--unit);
  border-bottom: 1px solid var(--rule);
}
.panel-head .label {
  font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
}
.panel--source .panel-head .label { color: var(--muted); }
.panel--plain  .panel-head .label { color: var(--accent); }
.wordcount { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

.panel p { font-size: 15px; line-height: 1.6; margin-bottom: .9em; }
.panel p:last-child { margin-bottom: 0; }
.panel .attribution { font-size: 11px; color: var(--muted); margin-top: calc(var(--unit) * 2); }

/* ---- CV ---------------------------------------------------------------- */

.cv-head { padding-block: calc(var(--unit) * 8) calc(var(--unit) * 4); border-bottom: 1px solid var(--rule); }
.cv-head h1 { grid-column: 1 / 8; font-size: clamp(2.5rem, 6vw, 4.5rem); margin-bottom: calc(var(--unit) * 2); }
.cv-head .cv-sub { grid-column: 1 / 8; font-size: 15px; color: var(--muted); }
/* The name and role are separate elements only so the print stylesheet can
   promote the name to the document title. The separator stays a real text
   node — CSS-generated content would drop out of the text layer, and this
   line has to survive being copied out of the page. Screen output is
   byte-identical to before the split. */
.cv-head .cv-contact { grid-column: 9 / -1; font-size: 12px; color: var(--muted); line-height: 1.7; border-top: 1px solid var(--rule); padding-top: calc(var(--unit) * 2); }
@media (max-width: 900px) { .cv-head h1, .cv-head .cv-sub, .cv-head .cv-contact { grid-column: 1 / -1; } .cv-head .cv-contact { margin-top: calc(var(--unit) * 2); } }

.cv-row { display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: 0 var(--gap); padding-block: calc(var(--unit) * 2); border-top: 1px solid var(--rule); }
.cv-when { grid-column: 1 / 3; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.cv-what { grid-column: 4 / -1; font-size: 14px; }
.cv-what strong { font-weight: 600; display: block; letter-spacing: -0.01em; }
.cv-what span { color: var(--muted); font-size: 13px; }
@media (max-width: 900px) {
  .cv-row { grid-template-columns: 1fr; row-gap: var(--unit); }
  .cv-when, .cv-what { grid-column: 1 / -1; }
}

/* CV list, carried over from the print-styled source page. Renamed from .pubs
   so it doesn't inherit the homepage's 12-column publication rows. */
.cv-body h2 {
  font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin: calc(var(--unit) * 6) 0 var(--unit);
  border-bottom: 1px solid var(--rule); padding-bottom: var(--unit);
}
.cv-body h2:first-child { margin-top: 0; }
.cv-pubs { list-style: none; margin: 0; padding: 0; counter-reset: cvp; }
.cv-pubs li { border-top: 1px solid var(--rule); padding-block: calc(var(--unit) * 2); font-size: 14px; }
.cv-pubs li:last-child { border-bottom: 1px solid var(--rule); }
.cv-pubs .title { font-weight: 600; display: block; margin-bottom: var(--unit); letter-spacing: -0.01em; }
.cv-pubs .authors { font-size: 12px; color: var(--muted); line-height: 1.55; }
.cv-pubs .authors b { color: var(--ink); font-weight: 700; }
.cv-pubs .venue { font-size: 12px; color: var(--muted); display: block; margin-top: calc(var(--unit) * .5); }
.cv-pubs .venue em { font-style: italic; color: var(--ink); }

/* A section heading already carries a rule; the first row beneath it must not
   add a second one. */
.cv-body h2 + .cv-row { border-top: 0; }
.cv-body h2 + .cv-pubs > li:first-child { border-top: 0; }


/* =========================================================================
   PRINT — the downloadable CV
   -------------------------------------------------------------------------
   cv.html is the single source for both the web page and assets/tyler-lewy-cv.pdf.
   Rendered with:  node tools/render_cv_pdf.js
   Keep the Swiss identity on paper — Inter, hairline rules, one accent on the
   section heads — but drop the screen furniture and the asymmetric gutter,
   which only wastes a page on Letter.
   ========================================================================= */

@media print {

  /* Dark mode must not follow the document onto paper. */
  :root {
    --ink:    #000000;
    --paper:  #FFFFFF;
    --grey:   #F5F5F5;
    --rule:   #000000;
    --muted:  #4A4A4A;   /* darker than screen --muted: pigment on white reads lighter than pixels */
    --accent: #D13A1E;
  }

  @page {
    size: Letter;
    margin: 14mm 16mm 18mm;
  }

  html, body {
    background: #fff;
    font-size: 9.5pt;
    line-height: 1.42;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* ---- Screen-only furniture ------------------------------------------- */
  .skip,
  .masthead,
  .colophon,
  .marker,
  .ext,
  .cv-contact a[href$=".pdf"],
  .cv-body > p:last-of-type      /* the "← Back to home" link */
  { display: none !important; }

  /* ---- Grid: collapse the 12-column screen layout ----------------------- */
  .grid {
    display: block;
    max-width: none;
    margin: 0;
    padding-inline: 0;
  }
  .section { border-bottom: 0; padding-block: 0; }
  .body-wide, .cv-body { grid-column: auto; }

  /* ---- Masthead block --------------------------------------------------- */
  .cv-head {
    padding-block: 0 calc(var(--unit) * 1.5);
    border-bottom: 1.5pt solid var(--ink);
    margin-bottom: calc(var(--unit) * 2);
  }
  .cv-head h1 {
    font-size: 22pt;
    letter-spacing: -0.04em;
    margin-bottom: 3pt;
  }
  /* On paper the masthead is gone, so this block is the whole letterhead and
     the name has to lead. "Curriculum vitae" demotes to a label. */
  .cv-head h1 {
    font-size: 8pt; font-weight: 600; letter-spacing: .11em;
    text-transform: uppercase; color: var(--muted);
    margin: 0 0 4pt; line-height: 1;
  }
  .cv-head .cv-sub { margin-bottom: 3pt; }
  .cv-sub .cv-name {
    display: block; font-size: 20pt; font-weight: 700;
    letter-spacing: -0.04em; line-height: 1.05; color: var(--ink);
  }
  .cv-sub .cv-sep { display: none; }
  .cv-sub .cv-role { display: block; font-size: 9.5pt; color: var(--ink); }
  .cv-head .cv-contact {
    font-size: 8.5pt;
    color: var(--muted);
    border-top: 0;
    padding-top: 0;
    line-height: 1.5;
  }
  /* One line, not a stacked block — paper has no column to hang it in. */
  .cv-head .cv-contact br { display: none; }
  .cv-head .cv-contact a { border-bottom: 0; color: var(--muted); }
  /* Every item after the first is a link, so a separator before each link
     yields "Hamilton, Montana · address · Google Scholar" on one line.
     Sibling selectors don't work here — the <br>s sit between the anchors. */
  .cv-head .cv-contact a::before { content: " · "; font-size: 8.5pt; }

  /* The address is assembled by site.js and rendered as the word "Email",
     which is useless on paper. Rebuild it from the same data attributes so
     the address is never duplicated in a second place. */
  a.js-email { font-size: 0 !important; }
  a.js-email::after {
    content: attr(data-user) "@" attr(data-domain);
    font-size: 8.5pt;
  }

  /* ---- Section heads ---------------------------------------------------- */
  .cv-body h2 {
    font-size: 8pt;
    letter-spacing: .11em;
    color: var(--accent);
    margin: 13pt 0 0;
    padding-bottom: 2.5pt;
    border-bottom: 0.75pt solid var(--ink);
    break-after: avoid;
    page-break-after: avoid;
  }
  .cv-body h2:first-child { margin-top: 0; }

  /* ---- Dated rows ------------------------------------------------------- */
  .cv-row {
    display: grid;
    grid-template-columns: 26mm 1fr;
    gap: 0 5mm;
    padding-block: 4pt;
    border-top: 0.4pt solid #B0B0B0;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cv-when { grid-column: 1; font-size: 8.5pt; color: var(--muted); }
  .cv-what { grid-column: 2; font-size: 9.5pt; }
  .cv-what strong { font-weight: 600; }
  .cv-what span.where { font-size: 8.5pt; color: var(--muted); display: block; }

  /* ---- Publications ----------------------------------------------------- */
  .cv-pubs li {
    border-top: 0.4pt solid #B0B0B0;
    padding-block: 4.5pt;
    font-size: 9.5pt;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cv-pubs li:last-child { border-bottom: 0; }
  .cv-pubs .title { margin-bottom: 2pt; }
  .cv-pubs .authors,
  .cv-pubs .venue { font-size: 8.2pt; line-height: 1.4; }
  .cv-pubs .venue { margin-top: 1pt; }

  /* Titles stay live links in the PDF, but must not print as coloured,
     underlined web links — the DOI is already spelled out beneath each one. */
  a, .paper, .cv-pubs .title a {
    color: var(--ink);
    border-bottom: 0;
    text-decoration: none;
  }

  .footnote {
    font-size: 8pt;
    border-top: 0.75pt solid var(--ink);
    padding-top: 4pt;
    margin-top: 12pt;
    break-inside: avoid;
  }

  /* Nothing should orphan a heading or strand two lines of a record. */
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
  ol, ul { break-before: avoid; }
}
