/* ---------------------------------------------------------------------------
   Typefaces, served from this origin. The woff2 files were pulled from Google
   once while authoring; the published page never requests anything off-site.

   Two voices, not three: Literata carries everything that is prose, Plex Mono
   carries everything that is data (the role line, the section heading, authors,
   venues, links). There is no sans.

   Literata is variable, so one file per subset covers the whole weight range.
   Plex Mono is not, so it needs a file per weight.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('/assets/fonts/literata-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('/assets/fonts/literata-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/plex-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/plex-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/plex-mono-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/plex-mono-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------------------
   Tokens.

   The light palette is defined on bare :root so it is never trapped inside a
   media query. Dark redefines only the tokens, in two places: under
   prefers-color-scheme for viewers who never touched the switch, and under
   [data-theme] so the switch wins in both directions.
   --------------------------------------------------------------------------- */

:root {
  --ground:      #fcfcfd;
  --text:        #15171c;
  --muted:       #5c6472;
  --faint:       #878e9c;
  --rule:        #e3e6ec;
  --accent:      #2a4d96;
  --accent-soft: rgba(42, 77, 150, 0.10);

  /* The toggle shows the theme you would switch TO. */
  --sun:  none;
  --moon: block;

  color-scheme: light;

  --font-prose: 'Literata', Charter, "Iowan Old Style", Georgia, serif;
  --font-mono:  'Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:      #0f1115;
    --text:        #e7e9ee;
    --muted:       #99a1b0;
    --faint:       #79808e;
    --rule:        #242832;
    --accent:      #93b3f2;
    --accent-soft: rgba(147, 179, 242, 0.14);
    --sun:  block;
    --moon: none;
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --ground:      #0f1115;
  --text:        #e7e9ee;
  --muted:       #99a1b0;
  --faint:       #79808e;
  --rule:        #242832;
  --accent:      #93b3f2;
  --accent-soft: rgba(147, 179, 242, 0.14);
  --sun:  block;
  --moon: none;
  color-scheme: dark;
}

:root[data-theme="light"] {
  --ground:      #fcfcfd;
  --text:        #15171c;
  --muted:       #5c6472;
  --faint:       #878e9c;
  --rule:        #e3e6ec;
  --accent:      #2a4d96;
  --accent-soft: rgba(42, 77, 150, 0.10);
  --sun:  none;
  --moon: block;
  color-scheme: light;
}

/* --------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--font-prose);
  font-size: 17px;
  /* 1.75 was generous to the point of stretching the page well past the old
     one for no gain in readability; 1.6 is still comfortable for a serif. */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--accent-soft); }

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

.page {
  /* 44rem puts the bio at ~72 characters a line, still inside the comfortable
     band and a little shorter down the page than 42rem's 69. */
  max-width: 44rem;
  margin: 0 auto;
  padding: 1.25rem 1.5rem 5rem;
}

/* --- theme switch --------------------------------------------------------- */

.toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 1.5rem;
}

#theme-toggle {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}

#theme-toggle:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

#theme-toggle svg { width: 17px; height: 17px; fill: currentColor; }
.icon-sun  { display: var(--sun); }
.icon-moon { display: var(--moon); }

/* --- masthead ------------------------------------------------------------- */

/* Centred rather than top-aligned: the portrait is much taller than the two
   lines of type beside it, and top-aligning leaves an obvious hole. */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding-bottom: 1.6rem;
  border-bottom: 1px solid var(--rule);
}

/* Sentence case, and large enough to actually top the hierarchy. The previous
   setting forced capitals with 0.115em of tracking at 1.55rem, which ranked the
   name below the 1.3rem publication titles and flattened the typeface in the one
   place it shows most. */
h1 {
  margin: 0;
  font-family: var(--font-prose);
  font-size: clamp(2rem, 1.5rem + 2.1vw, 2.6rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

.role {
  margin: 0.55rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.portrait {
  display: block;
  width: 148px;
  height: auto;
  flex: none;
  border-radius: 3px;
}

/* --- prose ---------------------------------------------------------------- */

.bio p {
  margin: 1.5rem 0 0;
  text-wrap: pretty;
}

.bio p:first-child { margin-top: 1.4rem; }

a {
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
  text-decoration-color: color-mix(in srgb, var(--accent) 38%, transparent);
  transition: text-decoration-color 120ms ease;
}

a:hover { text-decoration-color: var(--accent); }

/* --- publications --------------------------------------------------------- */

.publications {
  margin-top: 2.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

.section-label {
  margin: 0 0 1.35rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.pub {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: 1.6rem;
  align-items: start;
}

.pub + .pub { margin-top: 2rem; }

.thumb {
  width: 104px;
  aspect-ratio: 1;
  object-fit: cover;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: #fff;
}

/* The figures are all on white, which glares against the dark ground. Settle
   them slightly, and bring them fully up when the entry is hovered. */
:root[data-theme="dark"] .thumb { opacity: 0.88; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .thumb { opacity: 0.88; }
}
.pub:hover .thumb { opacity: 1; }

.pub h3 {
  margin: 0;
  font-family: var(--font-prose);
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.004em;
  text-wrap: pretty;
}

.pub h3 a {
  color: var(--text);
  text-decoration-color: transparent;
}

.pub h3 a:hover {
  color: var(--accent);
  text-decoration-color: color-mix(in srgb, var(--accent) 38%, transparent);
}

.authors {
  margin: 0.5rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--muted);
}

.authors b { font-weight: 600; color: var(--text); }

.venue {
  margin: 0.15rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--faint);
}

.note {
  margin: 0.8rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--muted);
  text-wrap: pretty;
}

.links {
  margin: 0.8rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.links a + a::before {
  content: "·";
  margin: 0 0.6em;
  color: var(--faint);
  text-decoration: none;
  display: inline-block;
}

/* --- footer --------------------------------------------------------------- */

footer {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.social {
  display: flex;
  align-items: center;
  gap: 1.35rem;
}

.social a {
  display: inline-flex;
  color: var(--faint);
  text-decoration: none;
  transition: color 120ms ease;
}

.social a:hover { color: var(--accent); }
.social svg { width: 18px; height: 18px; fill: currentColor; }

.colophon {
  margin: 1.75rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--faint);
}

/* --- narrow screens ------------------------------------------------------- */

@media (max-width: 34rem) {
  body { font-size: 16.5px; }
  .page { padding: 1rem 1.25rem 4rem; }
  .masthead { gap: 1.25rem; }
  .portrait { width: 108px; }
  h1 { letter-spacing: -0.012em; }
  .bio p:first-child { margin-top: 1.25rem; }
  .pub { grid-template-columns: 68px minmax(0, 1fr); gap: 1rem; }
  .thumb { width: 68px; }
  .pub h3 { font-size: 1.175rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
