/* Harvard Vision Sciences Lab
   Quiet and typographic: one serif, generous measure, restrained palette.
   Imagery carries the color. */

:root {
  /* the gradient runs --ground-edge at the corners to --ground at the centre,
     a much fainter reading of the wordmark's own background */
  --ground:      #f7f3e9;
  --ground-edge: #dfe9e8;
  --surface:     #fffdf8;

  --ink:         #0b344b;   /* the wordmark navy, verbatim */
  --muted:       #416570;
  --faint:       #53656d;   /* carries real content, so it clears AA too */
  --rule:        #dcd8c9;

  --accent:      #1b5e6d;   /* deep teal, from the iris */
  /* Hover state: the same teal family as --accent, several steps brighter and
     more saturated, so a title lights up rather than shifting a shade. At
     3.5:1 this is below the 4.5:1 body-text threshold, which is why hover also
     carries a glow and an underline — the affordance never rests on colour
     alone, and the resting state is comfortably AA. */
  --accent-lit:  #0f8fa1;
  --accent-glow: rgba(15, 143, 161, 0.32);
  --accent-soft: #e2ece9;

  --radius: 4px;
  --box-bg: var(--surface);
  --box-shadow: 0 1px 2px rgba(11, 52, 75, 0.05);
  --box-shadow-hover: 0 3px 12px rgba(11, 52, 75, 0.10);
  --figure-blend: multiply;
}

:root {
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
           Georgia, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
          Arial, sans-serif;

  --measure: 36rem;   /* prose column */
  --wide: 68rem;      /* page container */
}

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

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

/* The wordmark sits on a teal-to-cream gradient; this is a much fainter
   reading of it. Fixed attachment so it reads as one field behind the whole
   page rather than repeating per screenful, and painted on a flat --ground
   fallback so nothing depends on gradient support. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  background-image:
    radial-gradient(120% 80% at 50% 0%,
                    var(--ground) 0%,
                    var(--ground) 38%,
                    var(--ground-edge) 100%);
  background-attachment: fixed;
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.62;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
}

/* ---------- structure ---------- */

.wrap {
  max-width: var(--wide);
  margin: 0 auto;
  padding: 0 2rem;
}

.prose { max-width: var(--measure); }

main { flex: 1 0 auto; padding-bottom: 4rem; }

section + section { margin-top: 4.5rem; }

/* ---------- typography ---------- */

h1, h2, h3, h4 {
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.011em;
  margin: 0 0 0.6em;
}

h1 { font-size: clamp(2rem, 4.2vw, 2.85rem); }
h2 { font-size: clamp(1.45rem, 2.5vw, 1.85rem); margin-top: 0; }
h3 { font-size: 1.2rem; }

p { margin: 0 0 1.15em; }

a { color: inherit; text-decoration-color: var(--rule); text-underline-offset: 0.18em; }
a:hover { text-decoration-color: var(--accent); color: var(--accent); }

.lede {
  font-size: 1.24rem;
  line-height: 1.52;
  color: var(--ink);
}

/* Available to screen readers, invisible on screen. Used for headings that
   name a section the layout makes obvious visually. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- icons and placeholders ---------- */

.icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.18em;
}

/* Artwork not yet made. Visible on purpose — a blank slot reads as a bug,
   a labelled one reads as a to-do. */
.ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  aspect-ratio: 3 / 2;
  border: 1px dashed var(--rule);
  border-radius: var(--radius);
  background:
    repeating-linear-gradient(
      -45deg,
      var(--accent-soft) 0 10px,
      transparent 10px 20px);
  color: var(--faint);
}

.ph-icon { width: 1.7rem; height: 1.7rem; opacity: 0.55; }

.ph-label {
  font-family: var(--sans);
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-align: center;
  padding: 0 0.75rem;
}

.ph.wide   { aspect-ratio: 16 / 7; }

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

/* The header is built like the footer at the other end of the page: its own
   band, a hard accent edge facing the content, and its own text colours rather
   than the page's. That is what makes the two read as a matched frame around
   the content instead of three shades of the same gradient. */
.site-header {
  --head-text: #55737e;
  --head-link: #10505d;
  /* No band of its own: the header sits on the page ground and lets a soft
     shadow do the separating. A tinted bar plus a hairline stated the
     division twice, and the flat tone cut across the body gradient. */
  background: transparent;
  box-shadow: 0 10px 20px -16px rgba(11, 52, 75, 0.5);
}

.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-top: 0.9rem;
  padding-bottom: 0.9rem;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  color: inherit;
}
.wordmark:hover { color: inherit; }

/* The amodal mark: four inducers completing an illusory square. Transparent
   PNG tinted to --ink, so the band shows through the figure. */
.mark {
  width: 2.05rem;
  height: 2.05rem;
  flex: none;
  display: block;
}
.wordmark:hover .mark { opacity: 0.82; }

.wordmark-text {
  font-size: 1.18rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  line-height: 1.2;
  color: var(--ink);
  white-space: nowrap;
}

/* Small caps and wide tracking, matching the affiliation block in the footer —
   the two ends of the page use the same quiet register. Set several steps
   lighter than the navy above it so the two lines separate on colour as well
   as on size and case; still 4.5:1 on the page ground. */
.wordmark .sub {
  display: block;
  white-space: normal;
  font-family: var(--sans);
  font-size: 0.645rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--head-text);
  margin-top: 0.28rem;
}

nav.primary {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem;
  font-family: var(--sans);
  font-size: 0.815rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

nav.primary a {
  padding: 0.34rem 0.7rem;
  border-radius: 100px;
  text-decoration: none;
  color: var(--head-link);
  white-space: nowrap;
  transition: color 0.12s, background 0.12s;
}
nav.primary a:hover {
  color: var(--ink);
  background: rgba(11, 52, 75, 0.07);
}
nav.primary a[aria-current="page"] {
  color: var(--surface);
  background: var(--accent);
}
nav.primary a[aria-current="page"]:hover { color: var(--surface); }

/* Below the point where the two halves stop fitting side by side, the nav
   takes a row of its own with a rule above it, rather than wrapping raggedly
   into the wordmark's space. */
@media (max-width: 46rem) {
  .site-header .wrap {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-top: 0.8rem;
    padding-bottom: 0.15rem;
  }
  nav.primary {
    margin-top: 0.7rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--rule);
    gap: 0 0.05rem;
    justify-content: space-between;
    font-size: 0.78rem;
  }
  nav.primary a { padding: 0.4rem 0.4rem; }
  .wordmark-text { font-size: 1.08rem; white-space: normal; }
  .mark { width: 1.75rem; height: 1.75rem; }
}

@media (max-width: 26rem) {
  nav.primary { justify-content: flex-start; }
  nav.primary a { padding: 0.35rem 0.45rem; font-size: 0.75rem; }
  .wordmark .sub { letter-spacing: 0.16em; }
}

/* Pages open on their content, not on a heading repeating the nav. */
main > section:first-of-type { padding-top: 3rem; }
main > h1.visually-hidden + section { padding-top: 3rem; }

/* ---------- home: splash ---------- */

.splash { padding: 1.5rem 0 1rem; }

/* The panel overlaps the lower edge of the art rather than sitting on top of
   it — the eye and the mesh stay legible above, and the overlap is what ties
   the two together. A plain grid overlay covered the artwork it was meant to
   sit in. */
.splash-stage {
  position: relative;
  max-width: 58rem;
  margin: 0 auto;
  padding-bottom: 1rem;
}

.splash-art {
  display: block;
  width: 106%;
  max-width: none;
  height: auto;
  margin-left: -3%;
  opacity: 0.95;
}

.splash-panel {
  position: relative;
  z-index: 1;
  width: min(42rem, 94%);
  /* pulled well up into the art — the mesh stays visible around the panel's
     shoulders, and the page starts with far less empty run-out below */
  margin: -10rem auto 0;
  padding: 1.75rem 2.25rem 1.5rem;
  text-align: center;
  border-radius: calc(var(--radius) * 2);
  border: 1px solid rgba(255, 255, 255, 0.7);
  background: rgba(250, 247, 239, 0.9);
  -webkit-backdrop-filter: blur(8px) saturate(1.1);
  backdrop-filter: blur(8px) saturate(1.1);
  box-shadow:
    0 1px 2px rgba(11, 52, 75, 0.05),
    0 14px 44px rgba(11, 52, 75, 0.12);
}

/* The welcome sits above the mission line as a quiet greeting, not a
   heading of its own. */
.splash-welcome {
  margin: 0 0 0.6rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.splash-lede {
  margin: 0 0 0.9rem;
  font-size: clamp(1.35rem, 2.7vw, 1.8rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.018em;
  color: var(--ink);
  text-wrap: balance;
  max-width: 30em;
  margin-left: auto;
  margin-right: auto;
}

/* The questions run long, so they read left-aligned; the emphasized terms
   carry the scan down the block. */
.splash-questions {
  max-width: 36rem;
  margin: 0 auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
  color: var(--muted);
  text-align: left;
}
.splash-questions ul {
  list-style: disc;
  margin: 0;
  padding-left: 1.2rem;
}
.splash-questions li {
  font-size: 0.875rem;
  line-height: 1.55;
  margin: 0 0 0.75em;
  text-wrap: pretty;
}
.splash-questions li::marker { color: var(--faint); }
.splash-questions li:last-child { margin-bottom: 0; }
.splash-questions em {
  font-style: normal;
  font-weight: 650;
  color: var(--ink);
}

.splash-coda {
  max-width: 34rem;
  margin: 0.9rem auto 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
  font-size: 0.83rem;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

@media (max-width: 48rem) {
  .splash-panel { margin-top: -5.5rem; }
}
@media (max-width: 34rem) {
  .splash-art { width: 116%; margin-left: -8%; }
  .splash-panel { margin-top: -3rem; padding: 1.4rem 1.25rem 1.2rem; }
}

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

/* A line of choices divided by hairlines, not a panel of pills. It reads as
   one control and carries a fraction of the visual weight. */
.controls { margin-bottom: 1.9rem; }

.topicbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  font-family: var(--sans);
  font-size: 0.795rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--rule);
}

.topicopt {
  font: inherit;
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--muted);
  padding: 0.15rem 0.7rem;
  transition: color 0.12s;
}
.topicopt + .topicopt { border-left: 1px solid var(--rule); }
.topicopt:first-child { padding-left: 0; }
.topicopt:hover { color: var(--accent-lit); }
.topicopt[aria-current="true"] {
  color: var(--ink);
  font-weight: 700;
}

.pub-head {
  font-family: var(--sans);
  font-size: 0.73rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 2rem 0 1rem;
}
.pub-head:first-child { margin-top: 0; }

/* An earlier title the paper circulated under, shown in the topic
   spotlight only. */
.pub-alt {
  color: var(--muted);
  font-size: 0.82rem;
  font-style: italic;
  margin-top: 0.1rem;
}

/* Group headings inside "More publications on this topic" — one visual step
   down from .pub-head, indented to the shared title margin. */
.pub-subhead {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  margin: 1.4rem 0 0.5rem 3.3rem;
}

/* An entry is three tiers and should look like three: the title carries it,
   the byline supports it, and the links sit underneath at the smallest size. */
.pub {
  margin-bottom: 1.15rem;
  max-width: 52rem;
}

/* Entries reserve the same left column the compact list uses for its year, so
   both sets of titles sit on one margin. */
.pub.gutter {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 0.7rem;
  align-items: start;
}

.pub-title {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.32;
  color: var(--ink);
  text-decoration: none;
  margin-bottom: 0.12rem;
  transition: color 0.1s;
}
.pub-title:hover {
  color: var(--accent-lit);
  text-shadow: 0 0 14px var(--accent-glow);
}

.pdf-cue {
  font-family: var(--sans);
  font-size: 0.7em;
  margin-left: 0.3em;
  opacity: 0;
  transition: opacity 0.12s;
}
.pub-title:hover .pdf-cue { opacity: 0.75; }

.pub-meta {
  font-family: var(--sans);
  font-size: 0.765rem;
  color: var(--muted);
  line-height: 1.45;
}
.pub-meta .venue { color: var(--faint); }

.missing {
  color: #a3302a;
  font-weight: 700;
  margin-left: 0.45rem;
}

.empty {
  color: var(--muted);
  font-style: italic;
  padding: 2rem 0;
}

/* The compact list: everything else on a chosen topic, one line each. */
.pubbrief-list { max-width: 52rem; }

.pubbrief {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 0.1rem 0.7rem;
  padding: 0.4rem 0;
  align-items: baseline;
}

.pb-year {
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.pb-title {
  font-size: 0.885rem;
  line-height: 1.35;
  color: var(--ink);
  text-decoration: none;
  transition: color 0.1s;
}
.pb-title:hover {
  color: var(--accent-lit);
  text-shadow: 0 0 14px var(--accent-glow);
}

.pb-authors {
  grid-column: 2;
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--faint);
  line-height: 1.35;
}

/* The year stays flush to the page margin while the entries under it are
   indented past their link column, so the years read as a spine down the
   left edge. */
.year-head {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.9rem 0 0.8rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--rule);
  max-width: 52rem;
}
.year-head:first-of-type { margin-top: 0; }

/* ---------- publication footer: links and topics ---------- */

.pub-foot { margin-top: 0.25rem; }

/* Associated content sits inline on the byline, divided by pipes: a thread or
   a blog post is part of an entry's provenance, not a control under it. */
.pub-link {
  color: var(--accent);
  text-decoration: none;
}
.pub-link:hover { color: var(--accent-lit); text-decoration: underline; }

.pub-meta .pipe { color: var(--rule); padding: 0 0.1rem; }

.pub-topics {
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--faint);
  margin-left: auto;
}

.topiclink {
  font: inherit;
  border: 0;
  padding: 0;
  background: none;
  color: var(--faint);
  cursor: pointer;
}
.topiclink:hover { color: var(--accent); text-decoration: underline; }

.missing {
  color: #a3302a;
  font-weight: 700;
  margin-left: 0.45rem;
}

.year-head {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.9rem 0 0.75rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--rule);
  max-width: 52rem;
}
.year-head:first-of-type { margin-top: 0; }

@media (max-width: 40rem) {
  .pub-topics { margin-left: 0; flex-basis: 100%; }
}

/* ---------- people ---------- */

.era + .era {
  margin-top: 3.5rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
}

.era-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1rem;
  margin-bottom: 1.6rem;
}
.era-head h2 { font-size: 1.3rem; margin: 0; }

.era-note {
  font-family: var(--sans);
  font-size: 0.73rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}

/* One card size everywhere on the page, PIs and alumni included. The grid
   reads as one roster rather than as tiers of importance. */
.people-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 1.9rem 1.4rem;
}

/* A hairline plus a soft shadow: the border does the separating on a light
   photo, the shadow on a dark one. */
.person img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--surface);
  display: block;
  margin-bottom: 0.6rem;
  filter: saturate(0.94);
  box-shadow: 0 1px 3px rgba(11, 52, 75, 0.10),
              0 4px 12px rgba(11, 52, 75, 0.07);
}

/* A missing photo is a to-do, not a finished state. */
.person .nophoto {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  border: 1px solid #c46a63;
  background: #f0d9d6;
  color: #8d2c25;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  margin-bottom: 0.6rem;
}

.person .name {
  font-size: 0.97rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.008em;
  margin-bottom: 0.1rem;
}

.person .role {
  font-family: var(--sans);
  font-size: 0.715rem;
  color: var(--faint);
  line-height: 1.35;
}
.person .advisor { color: var(--faint); }
.person .pipe { color: var(--rule); padding: 0 0.1rem; }
.person-link { color: var(--accent); text-decoration: none; }
.person-link:hover { text-decoration: underline; }

.person .years {
  font-family: var(--sans);
  font-size: 0.68rem;
  color: var(--faint);
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
}

.person .now {
  font-size: 0.73rem;
  line-height: 1.35;
  color: var(--muted);
  margin-top: 0.15rem;
}

/* A date nobody has recorded is a to-do, not a finished state — the same
   argument as the missing-photo tile, in the space a year would occupy.
   Carries the red of that tile so the two read as one kind of gap. */

/* An estimated year still shows — "about 2013" beats a blank — but it never
   passes for a recorded one. The mark sits on the year itself: dotted,
   because the tooltip says where the guess came from and the underline is
   what invites the hover. */
.person .est {
  border-bottom: 1px dotted currentColor;
  cursor: help;
}

/* The PI card. Two roster columns wide, laid out as two equal halves with the
   roster's own gap between them — so the photo comes out exactly one column
   wide and everything on the page lines up on the same tracks. The extra room
   is spent on text, not on a bigger portrait. */
.person.wide {
  grid-column: span 2;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.4rem;
  align-items: start;
  /* The card is stretched to the height of its tallest sibling, and auto rows
     share that slack out between them. Stacked, that grew the photo's row and
     dropped the name below the neighbouring one. Pack the rows to the top and
     let the leftover space fall at the bottom. */
  align-content: start;
}

.person.wide img,
.person.wide .nophoto { margin-bottom: 0; }

.person.wide .name {
  font-size: 1.12rem;
  margin-bottom: 0.25rem;
}

/* Position, affiliations and links each get their own line: at this size they
   are three different kinds of fact, and running them together was what made
   the small card's single role line cramped. */
.person.wide .role { font-size: 0.75rem; }

.person.wide .affil {
  font-family: var(--sans);
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--muted);
  margin-top: 0.3rem;
}

.person.wide .pi-links {
  font-family: var(--sans);
  font-size: 0.75rem;
  margin-top: 0.55rem;
}
.person.wide .pi-links .pipe { color: var(--rule); padding: 0 0.35rem; }

/* Below the roster's two-column point a wide card has no second column to
   span into, so it stacks: photo over text, like every other card. */
@media (max-width: 34rem) {
  .person.wide {
    grid-column: span 1;
    grid-template-columns: 1fr;
    gap: 0.6rem;
  }
}

/* The compact card, for the historical roster. Smaller photo, tighter grid,
   and no website link — at this size the name and the years are the point,
   and an era of sixty reads as one block rather than sixty large cards. */
.people-grid.compact {
  grid-template-columns: repeat(auto-fill, minmax(6.75rem, 1fr));
  gap: 1.5rem 1.1rem;
}

.person.compact img,
.person.compact .nophoto { margin-bottom: 0.45rem; }

.person.compact .name {
  font-size: 0.83rem;
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: 0;
}

.person.compact .role { font-size: 0.67rem; line-height: 1.3; }
.person.compact .years { font-size: 0.65rem; margin-top: 0.1rem; }
.person.compact .now { font-size: 0.68rem; line-height: 1.3; }
.person.compact .nophoto { font-size: 0.8rem; }

/* ---------- george: about-me page ---------- */

/* Portrait, title and contact hold the first column; the bio and research
   sections read beside them at the site's prose measure. */
.bio-layout {
  display: grid;
  grid-template-columns: 13rem minmax(0, var(--measure));
  gap: 2rem 3.5rem;
}

/* The portrait file is already square; height:auto keeps its own ratio, so
   nothing here can stretch it. */
.bio-side img {
  width: 100%;
  max-width: 13rem;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--surface);
  display: block;
  margin-bottom: 0.9rem;
  filter: saturate(0.94);
  box-shadow: 0 1px 3px rgba(11, 52, 75, 0.10),
              0 4px 12px rgba(11, 52, 75, 0.07);
}

.bio-name {
  font-size: 1.12rem;
  font-weight: 600;
  line-height: 1.25;
}

.bio-role {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--faint);
  line-height: 1.4;
  margin-top: 0.15rem;
}

.bio-contact {
  font-family: var(--sans);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--muted);
  margin-top: 0.9rem;
}
.bio-contact a { color: var(--accent); text-decoration: none; }
.bio-contact a:hover { text-decoration: underline; }
.bio-contact address { font-style: normal; margin-top: 0.35rem; }
.bio-links { margin-top: 0.35rem; }
.bio-links .pipe { color: var(--rule); padding: 0 0.2rem; }

.bio-main h2 { margin-bottom: 0.6rem; }
.bio-main h2:first-child { margin-top: 0; }
.bio-main h2 + h2, .bio-main p + h2 { margin-top: 2.2rem; }

/* The banner art has a transparent ground, so it sits directly on the page —
   no frame, no radius. */
.bio-banner {
  width: 100%;
  height: auto;
  display: block;
  margin: 0.4rem 0 1.3rem;
}

@media (max-width: 52rem) {
  .bio-layout { grid-template-columns: 1fr; }
  .bio-side img { width: min(13rem, 60%); }
}

/* ---------- resources ---------- */

/* One card shape for image sets and code alike, small enough that the whole
   collection is visible at a glance. */
.res-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr));
  gap: 1.1rem 1rem;
  align-items: stretch;
}

.res-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--box-bg);
  overflow: hidden;
  transition: border-color 0.14s, box-shadow 0.14s;
}
.res-card:hover {
  border-color: var(--accent-lit);
  box-shadow: var(--box-shadow-hover);
}

/* Every card's art band is the same fixed height, with the image scaled
   down to fit inside it whatever its own aspect ratio — cropping a stimulus
   set would hide the thing it is showing. A hard height rather than an
   aspect-ratio so nothing about the image can change the band. White, not
   the surface tint, because nearly all the artwork is on white — contained
   images blend instead of floating in a visible letterbox. */
.res-art {
  height: 9.5rem;
  flex: 0 0 auto;
  overflow: hidden;
  background: #fff;
  border-bottom: 1px solid var(--rule);
}
.res-art img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  padding: 0.45rem;
}
.res-art .ph {
  border: 0;
  border-radius: 0;
  aspect-ratio: auto;
  height: 100%;
}

.res-body {
  padding: 0.65rem 0.75rem 0.75rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* The action sits to the left of the name and is the most saturated thing on
   the card — on a page of tools, "how do I get it" is the first question. */
.res-head {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
}

.res-act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  flex: none;
  border-radius: var(--radius);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--surface);
  transition: background 0.12s, border-color 0.12s;
}
.res-act:hover {
  background: var(--accent-lit);
  border-color: var(--accent-lit);
}
.res-act .icon { width: 1rem; height: 1rem; stroke-width: 1.9; }

.res-titles { min-width: 0; }

/* Sibling cards split out of one set keep the set's name above their own. */

.res-name {
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.25;
  margin: 0;
}
.res-card.code .res-name { font-family: var(--sans); font-size: 0.8rem; }

.res-desc {
  font-size: 0.75rem;
  line-height: 1.42;
  color: var(--muted);
  margin: 0.5rem 0 0;
}

/* The browse-the-set door under a card's title, set like a small label. */
.res-explore {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
  text-decoration: none;
  margin-top: 0.15rem;
}
.res-explore:hover { color: var(--accent-lit); text-decoration: underline; }

.res-cite { color: var(--faint); font-style: italic; }
a.res-cite { text-decoration: none; }
a.res-cite:hover { color: var(--accent-lit); text-decoration: underline; }

/* ---------- join ---------- */

.pos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.5rem;
  max-width: 52rem;
}

.pos {
  padding: 1.5rem 1.6rem 1.6rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--box-bg);
  box-shadow: var(--box-shadow);
}
.pos.open { border-top: 3px solid var(--accent); }

.pos-head { margin-bottom: 0.9rem; }

/* The status leads, because whether a position is open is the first thing
   anyone reading this page wants to know. */
.pos-status {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4rem;
}

.pos-title {
  font-size: 1.22rem;
  line-height: 1.2;
  margin: 0;
}

.pos p {
  font-size: 0.93rem;
  line-height: 1.58;
  color: var(--muted);
  margin: 0 0 0.8em;
}
.pos p:last-child { margin-bottom: 0; }


.eeo {
  max-width: 46rem;
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-family: var(--sans);
  font-size: 0.76rem;
  line-height: 1.6;
  color: var(--faint);
}

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

/* A darker band and a hard accent edge, so the page clearly ends rather than
   fading out. The three columns are typographically distinct: the lab's own
   address in ink, the two addresses you would actually write to as links, and
   the institutional affiliation set back in small caps. */
.site-footer {
  margin-top: 5rem;
  padding: 2.5rem 0 2.75rem;
  border-top: 2px solid var(--accent);
  background: linear-gradient(180deg, #c6d7d7 0%, #b2c8c9 100%);
  font-family: var(--sans);
  font-size: 0.79rem;
  line-height: 1.6;
  /* The band is darker than any page ground, so the footer carries its own
     two text colours rather than reusing --muted and --accent, which would
     drop under AA against it. Both clear 4.5:1 at the band's darkest point. */
  --foot-text: #2e4d57;
  --foot-link: #0d4956;
  color: var(--foot-text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45);
}

.foot-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.3fr);
  gap: 1.75rem 2.5rem;
  align-items: start;
}

.site-footer .addr {
  font-style: normal;
  color: var(--ink);
}
.site-footer .addr::first-line { font-weight: 700; }

.site-footer a {
  color: var(--foot-link);
  font-weight: 600;
  text-decoration: none;
}
.site-footer a:hover { color: var(--ink); text-decoration: underline; }

.foot-affil {
  display: flex;
  align-items: flex-start;
  gap: 1.1rem;
  justify-content: flex-end;
  text-align: right;
}
/* Five affiliations rather than three, so the leading tightens and the
   tracking comes in a little — at 1.85 the block ran taller than the shield
   beside it and read as a list instead of an address. */
.foot-affil > div {
  order: -1;
  font-size: 0.7rem;
  letter-spacing: 0.075em;
  text-transform: uppercase;
  line-height: 1.55;
  color: var(--foot-text);
}

.harvard-shield {
  height: 3.4rem;
  width: auto;
  flex: none;
}

@media (max-width: 52rem) {
  .foot-cols { grid-template-columns: 1fr; }
  .foot-affil { justify-content: flex-start; text-align: left; }
  .foot-affil > div { order: 0; }
}

/* ---------- responsive ---------- */

@media (max-width: 34rem) {
  .wrap { padding: 0 1.25rem; }
  .site-header .wrap { padding-top: 1.1rem; padding-bottom: 1.1rem; }
  nav.primary { margin-left: 0; gap: 1.1rem; width: 100%; }
  .questions { font-size: 1.15rem; }
}

/* ---------- print ---------- */

@media print {
  nav.primary, .controls, .site-footer { display: none; }
  body { background: #fff; color: #000; }
}

/* ---------- research: current-work showcase ---------- */

.showcase-intro {
  font-size: 0.98rem;
  color: var(--muted);
  margin: 0 0 1.5rem;
  max-width: 44rem;
}

.showcase-body {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 2.75rem;
  align-items: start;
}

/* Each themed group is one row: heading + list on the left, its figure on
   the right. Groups stack with air between them. */
.recent-group { margin-bottom: 3rem; }
.recent-group:last-child { margin-bottom: 0; }

.rg-head {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 0.9rem;
}

.sc-pipe { color: var(--faint); }

.sc-items {
  list-style: disc;
  margin: 0;
  padding-left: 1.2rem;
}
.sc-items li {
  margin-bottom: 0.45rem;
  line-height: 1.35;
}
.sc-items li::marker { color: var(--faint); }

/* The kind leads the line and the title runs on from it, so a reader gets
   what-it-is and what-it-was in one pass. */
.sc-kind {
  font-family: var(--sans);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
  margin-right: 0.5rem;
  white-space: nowrap;
}
a.sc-kind:hover { color: var(--accent-lit); text-decoration: underline; }

/* A kind with no conference page behind it yet. */
.missing-link {
  color: #a3302a;
  border-bottom: 1px dotted #a3302a;
  cursor: help;
}

/* Titles stay plain so the bold group headings carry the structure; the
   items then read as one tight block under their heading. */
.sc-title {
  font-size: 0.97rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--ink);
}

.sc-cite {
  display: block;
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--faint);
  margin-top: 0.15rem;
}

.showcase-figure { margin: 0; }
.showcase-figure img {
  width: 100%;
  max-height: 32rem;
  object-fit: contain;
  object-position: top;
  display: block;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--surface);
  padding: 0.4rem;
}

@media (max-width: 60rem) {
  .showcase-body { grid-template-columns: 1fr; gap: 2rem; }
}

/* ---------- research: bands and findings ---------- */

/* Band headings mark a boundary without shouting over what they introduce:
   letterspaced caps at nearly body size, the move the old konklab site made. */
.band-head {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 0.65rem;
  margin-bottom: 2rem;
  border-bottom: 2px solid var(--ink);
}

.band + .band { margin-top: 5rem; }

/* Five tiers inside a card, each visibly different from the next: the name of
   the line of work, the claim it makes, the question, the finding, and the
   papers. Previously these were all within a hair of each other in size and
   weight, which is what made it read as a wall. */
.finding {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  gap: 2.75rem;
  align-items: start;
  padding: 2.5rem 0;
  border-bottom: 1px solid var(--rule);
}
.finding:first-child { padding-top: 0.5rem; }
.finding:last-child { border-bottom: 0; }

.finding-title {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin-bottom: 0.6rem;
}
.finding-title a { text-decoration: none; }
.finding-title a:hover {
  color: var(--accent-lit);
  text-shadow: 0 0 16px var(--accent-glow);
}

/* The claim is the card's thesis and gets the strongest non-heading treatment:
   larger than the prose, medium weight, and marked off by a rule. */
.finding-claim {
  font-size: 1.12rem;
  font-weight: 500;
  line-height: 1.42;
  color: var(--accent);
  border-left: 2px solid var(--accent-soft);
  padding-left: 0.9rem;
  margin-bottom: 1.25em;
}

.finding-body > p {
  font-size: 0.93rem;
  line-height: 1.62;
  color: var(--muted);
  max-width: 40rem;
}
/* the question that opens the card carries a little more presence */
.finding-body > p.finding-claim + p { color: var(--ink); }

.finding-figure { margin: 0; }
.finding-figure img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--surface);
}

/* Papers are a labelled block, not a trailing paragraph. Titles are the
   scannable layer; citations recede into sans at the smallest size. */
.finding-refs {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

.finding-refs::before {
  content: "Key papers";
  display: block;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 0.7rem;
}

.ref { margin-bottom: 0.65rem; line-height: 1.38; }
.ref:last-child { margin-bottom: 0; }
.ref a {
  font-size: 0.89rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}
.ref a:hover { color: var(--accent-lit); text-decoration: underline; }

.ref-cite {
  display: block;
  font-family: var(--sans);
  font-size: 0.73rem;
  color: var(--faint);
  margin-top: 0.05rem;
}

.finding-more {
  margin: 1.35rem 0 0;
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
}
.finding-more a { color: var(--accent); text-decoration: none; }
.finding-more a:hover { text-decoration: underline; }

@media (max-width: 54rem) {
  .finding { grid-template-columns: 1fr; gap: 1.5rem; }
  .finding-figure { order: 2; }
  .finding-body { order: 1; }
  .finding-title { font-size: 1.32rem; }
}

/* ---------- talks ---------- */

.talk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.5rem;
}

/* A talk is a video. The still and the play badge say so before any text
   does, which is the point — this is the part of the research page you can
   engage with in one click. */
.talk-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--box-bg);
  box-shadow: var(--box-shadow);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.14s, box-shadow 0.14s, transform 0.14s;
}
.talk-card:hover {
  border-color: var(--accent);
  box-shadow: var(--box-shadow-hover);
  transform: translateY(-2px);
  color: inherit;
}

.talk-art { position: relative; }
.talk-art img {
  width: 100%;
  aspect-ratio: 16 / 7;
  object-fit: cover;
  display: block;
}
.talk-art .ph { border: 0; border-radius: 0; }

.talk-play {
  position: absolute;
  left: 0.85rem;
  bottom: 0.85rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--surface);
  color: var(--accent);
  box-shadow: var(--box-shadow);
}
.talk-play .icon { width: 1.05rem; height: 1.05rem; }

.talk-body { padding: 1.1rem 1.2rem 1.25rem; }

.talk-title {
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 0.3rem;
}
.talk-card:hover .talk-title {
  color: var(--accent-lit);
  text-shadow: 0 0 16px var(--accent-glow);
}

.talk-meta {
  font-family: var(--sans);
  font-size: 0.75rem;
  color: var(--faint);
  margin-bottom: 0.6rem;
}

.talk-body p {
  font-size: 0.89rem;
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
}

/* the secondary list: one line each, no artwork */
.talk-list {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  max-width: 52rem;
}
.talk-list li {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--rule);
}
.talk-list a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  font-size: 0.93rem;
  text-decoration: none;
  color: var(--ink);
}
.talk-list a:hover { color: var(--accent); }
.talk-list .icon { color: var(--accent); }
.talk-speaker {
  margin-left: auto;
  font-family: var(--sans);
  font-size: 0.75rem;
  color: var(--faint);
  white-space: nowrap;
}

/* ---------- a single topic page ---------- */

.crumb {
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--faint);
  margin-bottom: 1.5rem;
  display: flex;
  gap: 0.5rem;
}
.crumb a { color: var(--muted); text-decoration: none; }
.crumb a:hover { color: var(--accent); }

.topic-body {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 3rem;
  align-items: start;
  margin-top: 2rem;
}
.topic-body .prose { max-width: none; }
.topic-body em { font-style: italic; }

.topic-figure { margin: 0; }
.topic-figure img {
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
}
.topic-figure figcaption {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--faint);
  margin-top: 0.6rem;
  line-height: 1.5;
}

.topic-section {
  margin-top: 3.5rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
}
.topic-section h2 { font-size: 1.35rem; margin-bottom: 1.5rem; }

.topic-more {
  font-family: var(--sans);
  font-size: 0.85rem;
  margin-top: 1.5rem;
}
.topic-more a { color: var(--accent); text-decoration: none; }
.topic-more a:hover { text-decoration: underline; }

@media (max-width: 52rem) {
  .topic-body { grid-template-columns: 1fr; gap: 2rem; }
  .topic-figure { order: -1; }
}

/* ---------- topic pager ---------- */

.topic-pager {
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

.topic-pager h2 {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 1rem;
}

.topic-pager ul {
  list-style: disc;
  margin: 0;
  padding-left: 1.15rem;
  columns: 2;
  column-gap: 3rem;
  max-width: 46rem;
}

.topic-pager li {
  margin-bottom: 0.4rem;
  break-inside: avoid;
  color: var(--muted);
}

.topic-pager a { color: var(--accent); text-decoration: none; }
.topic-pager a:hover { text-decoration: underline; }

.topic-pager li.here {
  color: var(--ink);
  font-weight: 600;
  list-style-type: square;
}
.topic-pager li.here::marker { color: var(--accent); }

@media (max-width: 40rem) {
  .topic-pager ul { columns: 1; }
}

/* ---------- reduced motion ---------- */

/* Honour the OS setting: site.js smooth-scrolls when a topic pill is clicked,
   and boxes and chips animate on hover. None of it carries meaning. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .talk-card:hover { transform: none; }
}
