/* 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);
}

/* The link to the covering game (src/covering-game/, owned by the
   equivariant_transformers project): an icosahedron in place of its text, at
   the right end of the bar, lighting up when hovered. The text stays in the
   page for screen readers. The drawing is a mask, so it takes the colors
   above and follows dark mode. */
.navbar .nav-link[href*="covering-game"] .menu-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.navbar .nav-link[href*="covering-game"]::before {
  content: "";
  display: block;
  width: 1.25rem;
  height: 1.25rem;
  background-color: var(--ink-soft);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.3' stroke-linejoin='round'%3E%3Cpath d='M12 2 20.66 7 20.66 17 12 22 3.34 17 3.34 7Z M12 6.4 16.85 14.8 7.15 14.8Z M12 6.4 12 2 M12 6.4 20.66 7 M12 6.4 3.34 7 M16.85 14.8 20.66 17 M16.85 14.8 20.66 7 M16.85 14.8 12 22 M7.15 14.8 3.34 17 M7.15 14.8 3.34 7 M7.15 14.8 12 22'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.3' stroke-linejoin='round'%3E%3Cpath d='M12 2 20.66 7 20.66 17 12 22 3.34 17 3.34 7Z M12 6.4 16.85 14.8 7.15 14.8Z M12 6.4 12 2 M12 6.4 20.66 7 M12 6.4 3.34 7 M16.85 14.8 20.66 17 M16.85 14.8 20.66 7 M16.85 14.8 12 22 M7.15 14.8 3.34 17 M7.15 14.8 3.34 7 M7.15 14.8 12 22'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: background-color 0.2s ease, filter 0.2s ease;
}
.navbar .nav-link[href*="covering-game"]:hover::before {
  background-color: var(--accent);
  filter: drop-shadow(0 0 0.3rem 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; }
}

/* ---- The movie on the modular-addition page ------------------------ */
/* Portrait, 880 x 1092 at 1x. Full column width would put most of it below
   the fold on a laptop, so it is capped by the viewport height instead and
   centered; the intrinsic width/height on the element keep the space reserved
   while it loads. Autoplay is silent and looped, and it is muted so that
   every browser allows the autoplay. */
.movie {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 88vh;
  margin: 1.6rem auto 2rem;
  border-radius: 6px;
}

/* ---- Callout (the technical notes on the modular-addition page) ------- */
/* Quarto's "simple" callout, recolored to the palette: the accent as the left
   rule, the warm paper as the fill, no icon, and the theme's grey hairlines
   dropped. paper-warm is defined in both color schemes, so dark mode needs
   nothing more. The selectors carry three classes on purpose: the theme's
   own rules have two, and this file has to win. */
div.callout.callout-note.callout-style-simple {
  border-left: 4px solid var(--accent);
  border-top: none;
  border-right: none;
  border-bottom: none;
  border-radius: 4px;
  background: var(--paper-warm);
  padding: 0.7rem 1.1rem 0.45rem;
  margin: 2.2rem 0 1.5rem;
}
div.callout.callout-note.callout-style-simple > div.callout-header {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink-soft);
  opacity: 1;
  letter-spacing: 0.01em;
  margin-bottom: 0.2rem;
}
div.callout.callout-note.callout-style-simple .callout-body {
  font-size: 0.92rem;
  color: var(--ink);
}
div.callout.callout-note.callout-style-simple .callout-body ul {
  margin-bottom: 0.3rem;
  padding-left: 1.2rem;
}

/* ---- Math (MathML, modular-addition page only) ------------------------ */
/* A displayed equation gets a little room above and below; inline math is
   left to the browser. */
math[display="block"] { margin: 0.55rem 0; }

/* ---- 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; }
}
