/* ---------------------------------------------------------------
   Personal academic site — single stylesheet.
   Colors live in the :root block below; change them in one place.
   --------------------------------------------------------------- */

:root {
  --text:      #f2f0ed;   /* off-white body text */
  --muted:     #a9a7a3;   /* secondary text: dates, coauthors, labels */
  --rule:      #3a3c40;   /* hairline dividers */
  --bg:        #212326;   /* soft dark grey page background */
  --accent:    #ffce1c;   /* links + active tab */
  --bar:       #f2f0ed;   /* the mountain divider beside your photo */
  --highlight: #16181b;   /* near-black block behind the job title */

  /* Lato is loaded from Google Fonts in index.html — it isn't installed on
     any OS by default. The fallbacks cover the moment before it arrives, and
     visitors who block webfonts. */
  --sans: Lato, "Helvetica Neue", Helvetica, Arial, system-ui,
          -apple-system, sans-serif;
  --max-width: 44rem;
}

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

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

body {
  margin: 0 auto;
  padding: 3.5rem 1.5rem 4rem;
  max-width: var(--max-width);
  background-color: var(--bg);
  /* Barely-there texture: a 240px tile of tiny dots and dashes, half a touch
     lighter than the page and half a touch darker, all at 5-10% opacity. It
     should read as grain, not as a pattern. Delete this line to remove it. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'%3E%3Ccircle cx='116.0' cy='35.0' r='1.18' fill='%23ffffff' opacity='0.056'/%3E%3Ccircle cx='75.0' cy='225.3' r='0.72' fill='%23000000' opacity='0.096'/%3E%3Ccircle cx='169.1' cy='232.2' r='1.26' fill='%23ffffff' opacity='0.072'/%3E%3Ccircle cx='131.6' cy='15.8' r='0.99' fill='%23000000' opacity='0.063'/%3E%3Ccircle cx='41.3' cy='7.4' r='1.24' fill='%23ffffff' opacity='0.066'/%3E%3Ccircle cx='75.7' cy='144.2' r='1.06' fill='%23000000' opacity='0.091'/%3E%3Ccircle cx='127.9' cy='79.5' r='1.09' fill='%23ffffff' opacity='0.079'/%3E%3Ccircle cx='76.9' cy='79.5' r='1.36' fill='%23000000' opacity='0.068'/%3E%3Ccircle cx='109.0' cy='223.7' r='1.4' fill='%23ffffff' opacity='0.07'/%3E%3Ccircle cx='197.3' cy='120.9' r='0.71' fill='%23000000' opacity='0.065'/%3E%3Ccircle cx='177.8' cy='46.4' r='1.19' fill='%23ffffff' opacity='0.061'/%3E%3Ccircle cx='115.4' cy='84.3' r='0.69' fill='%23000000' opacity='0.074'/%3E%3Ccircle cx='120.4' cy='38.6' r='0.81' fill='%23ffffff' opacity='0.085'/%3E%3Ccircle cx='27.1' cy='157.1' r='0.93' fill='%23000000' opacity='0.09'/%3E%3Ccircle cx='33.7' cy='199.7' r='0.62' fill='%23ffffff' opacity='0.05'/%3E%3Ccircle cx='24.8' cy='91.5' r='0.61' fill='%23000000' opacity='0.065'/%3E%3Ccircle cx='97.7' cy='144.8' r='0.81' fill='%23ffffff' opacity='0.066'/%3E%3Ccircle cx='127.3' cy='201.7' r='1.02' fill='%23000000' opacity='0.076'/%3E%3Ccircle cx='102.9' cy='15.5' r='1.45' fill='%23ffffff' opacity='0.072'/%3E%3Ccircle cx='42.3' cy='184.2' r='0.7' fill='%23000000' opacity='0.082'/%3E%3Ccircle cx='47.5' cy='151.4' r='1.15' fill='%23ffffff' opacity='0.064'/%3E%3Ccircle cx='80.7' cy='188.4' r='0.89' fill='%23000000' opacity='0.06'/%3E%3Ccircle cx='121.9' cy='44.4' r='0.93' fill='%23ffffff' opacity='0.074'/%3E%3Ccircle cx='63.1' cy='27.1' r='1.2' fill='%23000000' opacity='0.089'/%3E%3Ccircle cx='187.9' cy='51.5' r='1.05' fill='%23ffffff' opacity='0.051'/%3E%3Ccircle cx='69.3' cy='104.5' r='1.19' fill='%23000000' opacity='0.092'/%3E%3Ccircle cx='213.5' cy='137.5' r='1.23' fill='%23ffffff' opacity='0.051'/%3E%3Ccircle cx='130.7' cy='159.4' r='1.1' fill='%23000000' opacity='0.098'/%3E%3Ccircle cx='123.1' cy='71.0' r='1.46' fill='%23ffffff' opacity='0.078'/%3E%3Ccircle cx='215.8' cy='34.3' r='0.9' fill='%23000000' opacity='0.071'/%3E%3Cline x1='176.7' y1='122.6' x2='181.9' y2='123.8' stroke='%23000000' stroke-width='0.8' stroke-linecap='round' opacity='0.085'/%3E%3Cline x1='56.0' y1='165.1' x2='62.6' y2='165.1' stroke='%23ffffff' stroke-width='0.85' stroke-linecap='round' opacity='0.051'/%3E%3Cline x1='121.6' y1='20.1' x2='128.5' y2='20.5' stroke='%23000000' stroke-width='1.05' stroke-linecap='round' opacity='0.086'/%3E%3Cline x1='74.4' y1='24.7' x2='80.0' y2='25.5' stroke='%23ffffff' stroke-width='0.95' stroke-linecap='round' opacity='0.073'/%3E%3Cline x1='153.1' y1='175.0' x2='157.8' y2='173.8' stroke='%23000000' stroke-width='0.93' stroke-linecap='round' opacity='0.082'/%3E%3Cline x1='93.8' y1='92.7' x2='98.2' y2='91.5' stroke='%23ffffff' stroke-width='0.71' stroke-linecap='round' opacity='0.072'/%3E%3Cline x1='219.8' y1='77.4' x2='226.9' y2='77.7' stroke='%23000000' stroke-width='0.86' stroke-linecap='round' opacity='0.07'/%3E%3Cline x1='115.6' y1='40.4' x2='123.8' y2='39.4' stroke='%23ffffff' stroke-width='0.99' stroke-linecap='round' opacity='0.066'/%3E%3Cline x1='154.9' y1='200.9' x2='162.0' y2='198.8' stroke='%23000000' stroke-width='1.03' stroke-linecap='round' opacity='0.058'/%3E%3Cline x1='125.7' y1='101.0' x2='132.1' y2='101.1' stroke='%23ffffff' stroke-width='0.72' stroke-linecap='round' opacity='0.062'/%3E%3Cline x1='94.5' y1='84.5' x2='100.6' y2='82.5' stroke='%23000000' stroke-width='0.79' stroke-linecap='round' opacity='0.071'/%3E%3Cline x1='46.5' y1='113.6' x2='54.6' y2='113.8' stroke='%23ffffff' stroke-width='0.73' stroke-linecap='round' opacity='0.065'/%3E%3Cline x1='113.5' y1='179.0' x2='121.4' y2='177.2' stroke='%23000000' stroke-width='1.07' stroke-linecap='round' opacity='0.074'/%3E%3Cline x1='128.8' y1='88.7' x2='134.7' y2='87.6' stroke='%23ffffff' stroke-width='0.85' stroke-linecap='round' opacity='0.06'/%3E%3Cline x1='200.0' y1='175.1' x2='207.3' y2='177.7' stroke='%23000000' stroke-width='0.88' stroke-linecap='round' opacity='0.055'/%3E%3Cline x1='55.8' y1='36.0' x2='59.5' y2='37.6' stroke='%23ffffff' stroke-width='0.89' stroke-linecap='round' opacity='0.052'/%3E%3Cline x1='60.7' y1='117.4' x2='68.9' y2='117.8' stroke='%23000000' stroke-width='0.73' stroke-linecap='round' opacity='0.07'/%3E%3Cline x1='16.3' y1='145.7' x2='22.4' y2='145.7' stroke='%23ffffff' stroke-width='0.89' stroke-linecap='round' opacity='0.045'/%3E%3C/svg%3E");
  color: var(--text);
  font: 400 1.0625rem/1.68 var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ----- links ----- */

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover { text-decoration: none; }

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

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  padding: .5rem .75rem;
  background: var(--bg);
  z-index: 1;
}

/* ----- header ----- */

h1 {
  margin: 0;
  font-size: 2.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.role {
  margin: .5rem 0 1.25rem;
  color: var(--muted);
  line-height: 1.5;
}

/* The affiliation line. Bold alone reads muddy in the muted grey, so it also
   takes the full text color — drop the `color` line to keep it grey. */
.role strong {
  font-weight: 700;
  color: var(--text);
}

/* The job-title line, highlighted against a near-black block.
   box-decoration-break keeps the padding correct if it wraps to two lines. */
.role-title {
  display: inline-block;
  margin-top: .3rem;
  padding: .12em .45em;
  background: var(--highlight);
  color: #fff;
  border-radius: 2px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.links a { overflow-wrap: anywhere; }

.links {
  margin: 0;
  font-family: var(--sans);
  font-size: .9375rem;
}

/* ----- tab bar ----- */

.tabs {
  display: flex;
  flex-wrap: wrap;
  margin-top: 2rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--sans);
  font-size: .9375rem;
}

.tabs a {
  margin: 0 1.75rem -1px 0;
  padding: .5rem 0 .55rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
.tabs a:last-child { margin-right: 0; }
.tabs a:hover { color: var(--text); }

.tabs a[aria-current] {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* ----- sections ----- */

/* Panels stack when JavaScript is unavailable; the .js class lets us show
   one at a time without a flash of all four on load. */
.panel { margin-top: 2.5rem; }

.js .panel { display: none; }
.js .panel.is-active { display: block; }

/* The tab bar already labels each panel, so these headings would read twice.
   Hide them visually but leave them in the accessibility tree — and bring
   them back when printing, where the tab bar isn't rendered. */
.panel > h2 {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* With the heading out of flow, whatever follows shouldn't add its own
   top margin on top of the panel's. */
.panel > h2 + * { margin-top: 0; }

h2 {
  margin: 0 0 1rem;
  font-size: 1.0625rem;
  font-weight: 600;
  font-family: var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

h3 {
  margin: 2rem 0 .75rem;
  font-size: 1.0625rem;
  font-weight: 600;
}

p { margin: 0 0 1rem; }

.interests {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
}
.interests li { margin-bottom: .25rem; }

/* ----- masthead: name block, vertical rule, photo at top right ----- */

.masthead {
  display: flex;
  gap: 1.75rem;
  /* align-items defaults to stretch, so the rule spans the full row height
     whether the text or the photo is taller. */
}

.masthead-text {
  flex: 1 1 auto;
  padding-right: 1.75rem;
  border-right: 3px solid var(--bar);
}
.masthead-text > :last-child { margin-bottom: 0; }

.bio-photo {
  flex: 0 0 10.5rem;
  width: 10.5rem;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  align-self: flex-start;
  border-radius: 2px;
}

/* ----- papers ----- */

.papers {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: paper;
}

.papers > li {
  margin-bottom: 2rem;
  padding-left: 1.75rem;
  position: relative;
  counter-increment: paper;
}
.papers > li::before {
  content: counter(paper) ".";
  position: absolute;
  left: 0;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.paper-title {
  margin: 0;
  font-weight: 600;
}

.paper-meta {
  margin: .15rem 0 0;
  color: var(--muted);
  font-size: .9375rem;
}

/* Your own name in an author list, so it's findable at a glance. */
.paper-meta strong {
  font-weight: 700;
  color: var(--text);
}

.paper-actions {
  display: flex;
  gap: .9rem;
  margin: .45rem 0 .35rem;
  font-family: var(--sans);
  font-size: .875rem;
}

details { font-size: .9375rem; }

summary {
  cursor: pointer;
  width: fit-content;
  color: var(--muted);
  font-family: var(--sans);
  font-size: .875rem;
}
summary:hover { color: var(--accent); }

details p {
  margin: .6rem 0 0;
  padding-left: .9rem;
  border-left: 2px solid var(--rule);
  color: var(--muted);
}

.wip {
  margin: 0;
  padding-left: 1.25rem;
}
.wip .paper-meta { display: inline; }
.wip li { margin-bottom: .5rem; }

/* ----- contact ----- */

/* Personal tab: label/value pairs. Wider label column than .contact because
   "Bouldering hold" needs the room. */
.favorites {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: .4rem 1rem;
  margin: 0;
}
.favorites dt {
  color: var(--muted);
  font-size: .9375rem;
  padding-top: .1rem;
}
.favorites dd { margin: 0; }

.grew-up { margin: 1.5rem 0 0; }

/* CV tab: the download link, then an inline preview sized like a page. */
.cv-link { margin-bottom: 1.25rem; }

.cv-preview {
  display: block;
  width: 100%;
  aspect-ratio: 8.5 / 11;
  margin: 0 0 2.5rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: #fff;
}

.contact {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: .4rem 1rem;
  margin: 0;
}
.contact dt {
  color: var(--muted);
  font-family: var(--sans);
  font-size: .875rem;
  padding-top: .1rem;
}
.contact dd { margin: 0; }

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

footer {
  margin-top: 4rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-family: var(--sans);
  font-size: .875rem;
}
footer p { margin: 0; }

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

@media (max-width: 42rem) {
  .cv-preview { display: none; }
}

@media (max-width: 30rem) {
  body { padding: 2.25rem 1.25rem 3rem; }
  h1 { font-size: 1.75rem; }
  .tabs a { margin-right: 1.25rem; }
  .masthead { flex-direction: column; gap: 1.25rem; }
  .masthead-text { padding-right: 0; border-right: 0; }
  .bio-photo { flex: 0 0 auto; width: 9rem; }
  .contact, .favorites { grid-template-columns: 1fr; gap: 0 0; }
  .contact dd, .favorites dd { margin-bottom: .75rem; }
}

/* ----- print (so Cmd-P gives a clean one-pager) ----- */

@media print {
  /* Paper is white, so flip back to ink-on-white and re-darken the rule. */
  :root {
    --text: #000; --muted: #444; --bg: #fff;
    --accent: #000; --bar: #000; --rule: #ccc;
  }
  /* No ink slab on paper — show the title as plain text. */
  .role-title { background: none; color: #000; padding: 0; }
  body { background-image: none; }
  .cv-preview { display: none; }   /* the CV prints on its own, not inside the page */
  .tabs, .skip, summary { display: none; }
  a { text-decoration: none; }
  .js .panel { display: block; }   /* print all four tabs, not just the open one */

  /* Tabs are hidden on paper, so the headings have to come back. */
  .panel > h2 {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 1rem;
    overflow: visible;
    clip-path: none;
  }
  .panel { break-inside: avoid; }
}
