/* Local styles only. No @import and no webfont host: everything this site
   loads is served from this site. Adding a font host here would be a request
   log kept by somebody else, and the output check fails the build over one. */

/* ---- The font -------------------------------------------------------- */
/* Source Sans 3, shipped with the site from fonts/ (SIL Open Font License,
   text in fonts/OFL.txt). Self-hosted so that every reader sees the same face,
   and in particular so the name, which is text, matches the alternative names
   beside it, which are outlines cut from the same font at build time. */

@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("fonts/SourceSans3-Regular.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: italic; font-weight: 400;
  font-display: swap; src: url("fonts/SourceSans3-It.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 500;
  font-display: swap; src: url("fonts/SourceSans3-Medium.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: normal; font-weight: 600;
  font-display: swap; src: url("fonts/SourceSans3-Semibold.woff2") format("woff2"); }
@font-face { font-family: "Source Sans 3"; font-style: italic; font-weight: 600;
  font-display: swap; src: url("fonts/SourceSans3-SemiboldIt.woff2") format("woff2"); }

:root {
  --paper:      #fcfbf9;
  --paper-warm: #f7f4ef;
  --ink:        #32353c;
  --ink-soft:   #646a7a;
  --accent:     #6b83bd;   /* soft periwinkle, a pastel of the CV's blue */
  --accent-deep:#4c64a0;
  --accent-wash:#edf0f8;
  --blush:      #f7eef2;
  --sage:       #ecf3f0;
  --rule:       #e7e3dc;
  --content-width: 42rem;
  --site-font: "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  --bs-font-sans-serif: var(--site-font);
  --bs-body-font-family: var(--site-font);
}

/* Base size for the whole page. Everything else is in rem, so this one number
   scales the site. 21.85px is 19 x 1.15, set on request on 2026-09-18. */
html { font-size: 21.85px; }

body {
  font-family: var(--site-font);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.72;
  -webkit-font-smoothing: antialiased;
}

main {
  max-width: var(--content-width);
  padding-bottom: 4rem;
}

/* ---- Headings -------------------------------------------------------- */

h1, h2, h3 { font-weight: 600; letter-spacing: -0.012em; color: var(--ink); }

h1.title {
  font-size: 2.1rem;
  line-height: 1.25;
  margin-bottom: 0.4rem;
}

/* A short accent rule under the page title: the same device that marks a
   section heading on the CV, so the two documents read as one hand. */
h1.title::after {
  content: "";
  display: block;
  width: 3.2rem;
  height: 3px;
  margin-top: 0.85rem;
  border-radius: 2px;
  background: var(--accent);
}

/* ---- The home page name line ---------------------------------------- */
/* The name is text; the alternative names are an inline SVG of glyph outlines
   INSIDE the same <h1>, because Quarto lifts the first <h1> of a page into its
   title block and would otherwise separate the two. Inline, so its generated
   negative bottom margin puts the outlines' baseline on the name's baseline,
   and so it wraps under the name when the line runs out. */

/* Styled like every other page's title, since it is one: same size, same
   accent rule under it. */
h1.site-name {
  font-size: 2.1rem;
  line-height: 1.25;
  margin-top: 1.4rem;
  margin-bottom: 0.4rem;
}
h1.site-name::after {
  content: "";
  display: block;
  width: 3.2rem;
  height: 3px;
  margin-top: 0.85rem;
  border-radius: 2px;
  background: var(--accent);
}

/* THE SIZE OF THE ALTERNATIVE NAMES: the value text is this size, the grey
   labels are 0.72 of it. The name is 2.1rem, so 1.3rem is about 0.6 of it. */
.alt-names {
  font-size: 1.3rem;
  margin-left: 1.1rem;
  vertical-align: baseline;
}
.alt-names .alt-value { fill: var(--ink); }
.alt-names .alt-label { fill: var(--ink-soft); }

/* On a phone the line cannot fit beside the name, so it takes its own line,
   unindented, and shrinks to the column if it has to. */
@media (max-width: 40rem) {
  /* !important because the baseline margin is an inline style: once the line
     has wrapped there is no baseline to align, and it would pull the rule up. */
  .alt-names { display: block; margin-left: 0; margin-top: 0.45rem; font-size: 1.15rem;
               margin-bottom: 0 !important; }
}

h2 {
  font-size: 1.32rem;
  margin-top: 2.6rem;
  margin-bottom: 0.7rem;
}

.subtitle, p.subtitle {
  font-weight: 400;
  font-size: 1.05rem;
  color: var(--ink-soft);
  margin-top: 0.9rem;
}

/* ---- Links ----------------------------------------------------------- */

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

/* ---- Navigation ------------------------------------------------------ */

.navbar {
  background: var(--paper-warm) !important;
  border-bottom: 1px solid var(--rule);
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}
.navbar .navbar-brand, .navbar .nav-link {
  color: var(--ink) !important;
  font-size: 0.92rem;
}
.navbar .navbar-brand { font-weight: 600; }
.navbar .nav-link:hover { color: var(--accent-deep) !important; }
.navbar .nav-link.active {
  color: var(--accent-deep) !important;
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* ---- Publication and talk lists -------------------------------------- */

.publist ul { list-style: none; padding-left: 0; margin-top: 1.4rem; }

.publist li {
  position: relative;
  padding: 0.55rem 0 0.7rem 1.35rem;
  margin-bottom: 0.35rem;
  border-bottom: 1px solid var(--rule);
}
.publist li:last-child { border-bottom: none; }

.publist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.22rem;
  width: 0.46rem;
  height: 0.46rem;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.55;
}

.publist strong { font-weight: 600; }

.pub-meta {
  display: inline-block;
  margin-top: 0.15rem;
  font-size: 0.86rem;
  color: var(--ink-soft);
  letter-spacing: 0.005em;
}

/* ---- News timeline --------------------------------------------------- */
/* Three columns per entry: the date, a rail carrying the string and its blob,
   and the text. Each entry is its own grid, so the rail only stretches to the
   entry's content box and the gap below it would cut the string. The line is
   therefore extended downward by exactly the gap, which is why both come from
   one variable. */

.timeline { margin-top: 2rem; --tl-gap: 1.7rem; }

.tl-item {
  display: grid;
  grid-template-columns: 6.4rem 1.8rem 1fr;
  align-items: start;
  padding-bottom: var(--tl-gap);
}

.tl-date {
  text-align: right;
  font-size: 1.05rem;         /* a touch larger than the body text */
  font-weight: 500;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  padding-top: 0.02rem;
  white-space: nowrap;
}

.tl-rail { position: relative; align-self: stretch; }

/* The string. It runs the full height of the entry and on into the gap, so
   one entry's line meets the next one's. */
.tl-rail::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: calc(-1 * var(--tl-gap));
  width: 2px;
  transform: translateX(-50%);
  background: var(--rule);
}
/* The first entry's line starts at its blob rather than above it, and the
   last entry has no line below it at all. */
.tl-item:first-child .tl-rail::before { top: 0.72rem; }
.tl-item:last-child .tl-rail::before { display: none; }

/* The blob. The ring is the page color, so the string appears to pass behind
   it rather than through it. */
.tl-rail::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0.72rem;
  width: 0.62rem;
  height: 0.62rem;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--paper);
}

.tl-body { padding-top: 0.02rem; }

@media (max-width: 34rem) {
  .tl-item { grid-template-columns: 4.9rem 1.4rem 1fr; }
  .tl-date { font-size: 0.98rem; }
}

/* ---- Footer ---------------------------------------------------------- */

.nav-footer {
  background: var(--paper-warm);
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 0.84rem;
  margin-top: 3rem;
}

/* ---- The placeholder banner ------------------------------------------ */
/* Shown only in a placeholder build; a real build writes an empty file, so
   this rule then has nothing to style. Deliberately the one loud thing on
   the page. */

.placeholder-banner {
  background: #8c3b4a;
  color: #fff;
  padding: 0.65rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
}

/* ---- Dark mode ------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #23262c;
    --paper-warm: #282c33;
    --ink:        #e4e1db;
    --ink-soft:   #a5a9b4;
    --accent:     #9fb2e0;
    --accent-deep:#b7c5e8;
    --rule:       #383d46;
  }
  body { background: var(--paper); color: var(--ink); }
  h1, h2, h3 { color: var(--ink); }
  .navbar .navbar-brand, .navbar .nav-link { color: var(--ink) !important; }
}
