/* ============================================================
   Shared theme, used by every page of the site.
   Change a value here and it changes everywhere.
   ============================================================ */

:root {
  /* Colour */
  --bg:        #FCFAF6;   /* warm paper */
  --ink:       #16171A;   /* headings */
  --body:      #44464B;   /* body copy */
  --muted:     #84868C;   /* captions, eyebrows */
  --rule:      #E7E0D3;   /* hairlines */
  --accent:    #A8AAAF;   /* light grey, underlines and accents */
  --accent-dk: #26272C;   /* near-black, buttons and triad words */


  /* Type */
  --sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Rhythm */
  --gutter: clamp(1.5rem, 5vw, 4.5rem);
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* The entrance animation slides the triad in from off-centre, which can
   momentarily poke past a narrow viewport. `clip` suppresses that sideways
   scroll without creating a scroll container, so the sticky year headings on
   the news and publications pages keep working. */
html, body { overflow-x: clip; }
body, h1, h2, h3, p, ul, dl, dd, figure { margin: 0; }
ul { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }

/* ---------- page shell ---------- */
body {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--body);
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.site-header, .stage, .doc, .site-footer { position: relative; z-index: 1; }

/* ============================================================
   Header
   ============================================================ */
.site-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding: clamp(1.4rem, 2.8vw, 2.3rem) var(--gutter);
}

.wordmark {
  font-size: 1.14rem;
  font-weight: 500;
  letter-spacing: -0.018em;
  color: var(--ink);
  text-decoration: none;
}
.wordmark span { font-weight: 400; color: var(--muted); }

.site-nav ul {
  display: flex;
  gap: clamp(1.25rem, 3vw, 2.6rem);
}
.site-nav a {
  font-size: 0.92rem;
  font-weight: 400;
  letter-spacing: -0.005em;
  text-transform: lowercase;
  color: var(--muted);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color .25s ease, border-color .25s ease;
}
.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

/* ============================================================
   Landing page: watercolour ground, hero left, DAG plate right.
   ============================================================ */

.ground {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  filter: blur(56px);
  opacity: .62;
}
.ground b {
  position: absolute;
  display: block;
  mix-blend-mode: multiply;
  border-radius: 46% 54% 58% 42% / 48% 44% 56% 52%;
}
.stain-1 { width: 62vw; height: 74vh; right: -8vw; top:  8vh; background: #3B7EA8; opacity: .13; animation: stain-a 52s ease-in-out infinite; }
.stain-2 { width: 40vw; height: 44vh; left:   2vw; bottom: 2vh; background: #E4593F; opacity: .09; animation: stain-b 45s ease-in-out infinite; }

@keyframes stain-a { 50% { transform: translate(-3vw, 4vh) scale(1.10); } }
@keyframes stain-b { 50% { transform: translate( 2vw,-4vh) scale(1.06); } }

@media (prefers-reduced-motion: reduce) { .ground b { animation: none; } }

.stage {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr minmax(0, 44%);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  padding: 0 var(--gutter) clamp(2rem, 5vh, 3.5rem);
}

.hero { max-width: 34rem; }

.eyebrow {
  font-size: 0.71rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  line-height: 1.85;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.4rem;
}

h1 {
  font-weight: 200;
  font-size: clamp(2.35rem, 4.6vw, 3.4rem);
  line-height: 1.06;
  letter-spacing: -0.024em;
  color: var(--ink);
}

/* ---------- Observe · Infer · Act ---------- */
.triad {
  display: grid;
  grid-template-columns: max-content max-content;
  align-items: baseline;
  margin-top: clamp(1.6rem, 3.4vh, 2.2rem);
}
.triad dt {
  font-size: clamp(1.12rem, 1.7vw, 1.34rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.017em;
  color: var(--ink);
  text-align: right;
  padding: 0.5rem clamp(0.9rem, 2vw, 1.6rem) 0.5rem 0;
}
.triad dd {
  font-size: 0.97rem;
  line-height: 1.3;
  letter-spacing: -0.004em;
  color: var(--muted);
  text-align: left;
  padding: 0.58rem 0 0.58rem clamp(0.9rem, 2vw, 1.6rem);
  border-left: 1px solid var(--rule);
}

.lede {
  max-width: 54ch;
  margin-top: clamp(1.7rem, 3.6vh, 2.3rem);
  font-size: clamp(1rem, 1.3vw, 1.1rem);
  line-height: 1.7;
  letter-spacing: -0.009em;
  color: var(--body);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem 2rem;
  margin-top: clamp(1.7rem, 3.6vh, 2.3rem);
}

.btn {
  display: inline-block;
  padding: 0.8rem 1.85rem;
  border-radius: 999px;
  background: var(--accent-dk);
  color: #fff;
  font-size: 0.87rem;
  font-weight: 500;
  letter-spacing: -0.002em;
  text-decoration: none;
  transition: background .25s ease, transform .25s ease;
}
.btn:hover { background: #000; transform: translateY(-1px); }

.btn-quiet {
  font-size: 0.87rem;
  font-weight: 500;
  letter-spacing: -0.002em;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  transition: border-color .25s ease;
}
.btn-quiet:hover { border-bottom-color: var(--accent); }
.btn-quiet span { transition: margin-left .25s ease; margin-left: .35rem; display: inline-block; }
.btn-quiet:hover span { margin-left: .6rem; }

/* ---------- the plate of standard DAGs ---------- */
.field {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.9rem, 2vw, 1.8rem);
}
.dcard { margin: 0; display: flex; flex-direction: column; align-items: center; gap: .4rem; }
.dcard svg { width: 100%; height: auto; overflow: visible; }
.dcard figcaption {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.dcard .w circle { opacity: .42; }
.dcard .i line   { stroke: var(--dag-ink); stroke-width: 2.2; stroke-linecap: round; fill: none; }
.dcard .i circle { fill: var(--bg); stroke: var(--dag-ink); stroke-width: 2.2; }
/* Labels are positioned at their exact point, so centre them on both axes
   rather than sitting them on a baseline. */
.dcard .t text   { font: 600 9px var(--sans); fill: var(--ink);
                   text-anchor: middle; dominant-baseline: central; }

@media (prefers-reduced-motion: no-preference) {
  .dcard .i line {
    stroke-dasharray: 120; stroke-dashoffset: 120;
    animation: dag-draw .8s ease forwards;
    animation-delay: calc(.25s + var(--d) * .16s);
  }
  .dcard .i circle, .dcard .t {
    opacity: 0;
    animation: dag-fade .6s ease forwards;
    animation-delay: calc(.55s + var(--d) * .16s);
  }
  /* The wash blooms in. The slow attention sweep deepens the pigment
     of the circles themselves; it must NOT animate `filter` on the group,
     because a CSS filter overrides the SVG filter= attribute and the
     watercolour would flatten into plain discs. */
  .dcard .w {
    opacity: 0;
    animation: dag-fade 1.4s ease forwards;
    animation-delay: calc(.8s + var(--d) * .16s);
  }
  .dcard .w circle {
    animation: dag-sweep 15s ease-in-out infinite;
    animation-delay: calc(var(--d) * 2.5s);
  }
  @keyframes dag-draw  { to { stroke-dashoffset: 0; } }
  @keyframes dag-fade  { to { opacity: 1; } }
  @keyframes dag-sweep { 0%, 88%, 100% { opacity: .42; } 44% { opacity: .60; } }
}

@media (max-width: 860px) {
  .stage { grid-template-columns: 1fr; align-items: start; padding-top: 1rem; }
  .field { grid-template-columns: repeat(3, 1fr); margin-top: 2.6rem; }
}
@media (max-width: 560px) {
  .field { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .6rem 2rem;
  padding: 1.6rem var(--gutter) 2rem;
  font-size: 0.75rem;
  letter-spacing: -0.002em;
  color: var(--muted);
}
.site-footer a { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.site-footer a:hover { border-bottom-color: var(--rule); }

.social { display: flex; align-items: center; gap: 1.15rem; }
.social a {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-bottom: 0;
  color: var(--muted);
  transition: color .2s ease, transform .2s ease;
}
.social a:hover { color: var(--ink); transform: translateY(-1px); border-bottom: 0; }
.social svg { width: 100%; height: 100%; fill: currentColor; display: block; }

/* ============================================================
   Small screens
   ============================================================ */
@media (max-width: 760px) {
  .site-header { flex-direction: column; align-items: center; gap: 1rem; text-align: center; }
  .eyebrow { font-size: 0.62rem; letter-spacing: 0.14em; }
  .site-footer { justify-content: center; text-align: center; }

  .triad { grid-template-columns: 1fr; }
  .triad dt { text-align: center; padding: 0 0 0.15rem; }
  .triad dd { text-align: center; border-left: 0; padding: 0 0 1.1rem; }
  .triad dd:last-of-type { padding-bottom: 0; }
}

/* ============================================================
   Entrance, plays once on load.
   The triad splits apart: the word travels left, its meaning
   travels right, away from a shared centre line.
   ============================================================ */

@keyframes rise      { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes part-left { from { opacity: 0; transform: translateX(34px);  } to { opacity: 1; transform: none; } }
@keyframes part-right{ from { opacity: 0; transform: translateX(-34px); } to { opacity: 1; transform: none; } }

.hero .eyebrow { animation: rise .75s cubic-bezier(.22,.7,.25,1) .05s both; }
.hero h1       { animation: rise .85s cubic-bezier(.22,.7,.25,1) .18s both; }
.hero .lede    { animation: rise .85s cubic-bezier(.22,.7,.25,1) 1.02s both; }
.hero .actions { animation: rise .85s cubic-bezier(.22,.7,.25,1) 1.16s both; }

.triad dt { animation: part-left  .95s cubic-bezier(.19,.82,.25,1) both; }
.triad dd { animation: part-right .95s cubic-bezier(.19,.82,.25,1) both; }

.triad dt:nth-of-type(1), .triad dd:nth-of-type(1) { animation-delay: .50s; }
.triad dt:nth-of-type(2), .triad dd:nth-of-type(2) { animation-delay: .64s; }
.triad dt:nth-of-type(3), .triad dd:nth-of-type(3) { animation-delay: .78s; }

@media (prefers-reduced-motion: reduce) {
  .hero .eyebrow, .hero h1, .hero .lede, .hero .actions,
  .triad dt, .triad dd { animation: none; }
}

/* ============================================================
   Long-form text pages (research, and anything like it).
   Shares the header, footer and emblem with the landing page;
   only the body column differs.
   ============================================================ */

.doc {
  flex: 1;
  width: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vh, 3.5rem) var(--gutter) clamp(3rem, 8vh, 5rem);
}

.doc h1 {
  font-weight: 200;
  font-size: clamp(2.1rem, 4.2vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.024em;
  color: var(--ink);
  margin-bottom: 1.6rem;
}

.doc .intro p {
  font-size: clamp(1.02rem, 1.3vw, 1.13rem);
  line-height: 1.72;
  letter-spacing: -0.009em;
  color: var(--body);
  margin-bottom: 1.1rem;
}

.doc section { margin-top: clamp(2.8rem, 6vh, 4.2rem); }

.doc h2 {
  font-size: clamp(1.3rem, 2.1vw, 1.62rem);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.2;
  color: var(--ink);
}

/* the one-line claim under each heading, echoing the triad's hairline */
.doc .claim {
  margin: 1rem 0 1.4rem;
  padding-left: clamp(0.9rem, 2vw, 1.4rem);
  border-left: 1px solid var(--rule);
  font-size: 1.02rem;
  line-height: 1.55;
  letter-spacing: -0.011em;
  color: var(--ink);
}

.doc section p {
  font-size: 0.995rem;
  line-height: 1.78;
  letter-spacing: -0.005em;
  color: var(--body);
  margin-bottom: 1.05rem;
}

/* back to the landing page */
.doc .back {
  margin-top: clamp(3rem, 7vh, 4.5rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule);
}
.doc .back a {
  font-size: 0.87rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}
.doc .back a span {
  display: inline-block;
  margin-right: .4rem;
  transition: margin .25s ease;
}
.doc .back a:hover span { margin-right: .65rem; margin-left: -.25rem; }

/* gentle entrance, heading block only */
.doc h1        { animation: rise .8s cubic-bezier(.22,.7,.25,1) .05s both; }
.doc .intro    { animation: rise .8s cubic-bezier(.22,.7,.25,1) .18s both; }

@media (prefers-reduced-motion: reduce) {
  .doc h1, .doc .intro { animation: none; }
}

/* ============================================================
   The three research areas.
   A numbered row: each title is a button that opens its write-up
   in a dialog. The row itself never changes height.
   ============================================================ */

.steps {
  width: min(62rem, calc(100vw - 2 * var(--gutter)));
  margin: clamp(2.2rem, 5vh, 3.2rem) 0 clamp(1.2rem, 3vh, 2rem);
  margin-left: 50%;
  transform: translateX(-50%);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: clamp(1.6rem, 3.5vw, 2.8rem);
  list-style: none;
  padding: 0;
}

.steps li { border-top: 1px solid var(--rule); padding-top: 1.05rem; }

.step-num {
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

.step-title { margin: 0 0 0.55rem; }

.step-open {
  position: relative;
  display: block;
  width: 100%;
  padding: 0 1.6rem 0 0;
  font: inherit;
  font-size: 1.03rem;
  font-weight: 500;
  letter-spacing: -0.022em;
  line-height: 1.3;
  color: var(--ink);
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}
.step-open .plus {
  position: absolute;
  right: 0;
  top: -0.02em;
  font-weight: 400;
  color: var(--muted);
  transition: color .2s ease, transform .3s cubic-bezier(.2,.7,.2,1);
}
.step-open:hover .plus,
.step-open:focus-visible .plus { color: var(--ink); transform: rotate(90deg); }
.step-open:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rule); }
.step-open:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.step-desc {
  font-size: 0.87rem;
  line-height: 1.6;
  letter-spacing: -0.005em;
  color: var(--body);
}

/* ============================================================
   The write-up dialog. One design for all three.
   Fades and lifts in, fades out, using CSS only.
   ============================================================ */

.panel {
  width: min(40rem, calc(100vw - 2.5rem));
  max-height: min(84vh, 46rem);
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: var(--bg);
  color: var(--body);
  box-shadow: 0 24px 70px rgba(0,0,0,.15), 0 2px 8px rgba(0,0,0,.05), 0 0 0 1px rgba(0,0,0,.05);
  overflow: hidden;

  opacity: 0;
  transform: translateY(14px) scale(.985);
  transition:
    opacity .3s ease,
    transform .34s cubic-bezier(.2,.75,.25,1),
    overlay .34s allow-discrete,
    display .34s allow-discrete;
}
.panel[open] { opacity: 1; transform: none; }
@starting-style {
  .panel[open] { opacity: 0; transform: translateY(14px) scale(.985); }
}

.panel::backdrop {
  background: rgba(252, 252, 252, 0.72);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .3s ease, overlay .3s allow-discrete, display .3s allow-discrete;
}
.panel[open]::backdrop { opacity: 1; }
@starting-style {
  .panel[open]::backdrop { opacity: 0; }
}

.panel-body {
  max-height: min(84vh, 46rem);
  overflow-y: auto;
  padding: clamp(2rem, 4.5vw, 3rem);
}

.panel-num {
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--muted);
  margin-bottom: 0.8rem;
}
.panel-body h2 {
  font-size: clamp(1.3rem, 2.2vw, 1.62rem);
  font-weight: 500;
  letter-spacing: -0.026em;
  line-height: 1.2;
  color: var(--ink);
}
.panel-lead {
  margin: 1rem 0 1.5rem;
  padding-left: clamp(.9rem, 2vw, 1.3rem);
  border-left: 1px solid var(--rule);
  font-size: 1rem;
  line-height: 1.55;
  letter-spacing: -0.011em;
  color: var(--ink);
}
.panel-body p + p { margin-top: 1rem; }
.panel-body > p:not(.panel-lead) {
  font-size: 0.94rem;
  line-height: 1.78;
  letter-spacing: -0.005em;
  color: var(--body);
}

.panel-close {
  position: absolute;
  top: .8rem;
  right: 1rem;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.panel-close:hover { background: #F0F0F0; color: var(--ink); }
.panel-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .panel, .panel::backdrop { transition: none; }
  .step-open .plus { transition: color .2s ease; }
  .step-open:hover .plus { transform: none; }
}

/* ============================================================
   The DAG above each area, in ink and wash.
   Two layers: a watercolour that sits slightly off its node, and
   a hand-wobbled ink line over it. Both are SVG filters, no images.
   ============================================================ */

:root {
  --dag-ink: #2A2723;   /* the drawn line */
  --dag-size: 104px;
}

.dag {
  display: block;
  width: var(--dag-size);
  height: auto;
  margin-bottom: 1.15rem;
  overflow: visible;
}
.dag-wash circle { opacity: .5; }
.dag-ink line   { stroke: var(--dag-ink); stroke-width: 2.1; stroke-linecap: round; fill: none; }
.dag-ink circle { fill: var(--bg); stroke: var(--dag-ink); stroke-width: 2.1; }
marker path { fill: var(--dag-ink); }

@media (prefers-reduced-motion: no-preference) {
  .dag-ink line {
    stroke-dasharray: 90;
    stroke-dashoffset: 90;
    animation: dag-draw .9s cubic-bezier(.3,.7,.3,1) forwards;
  }
  .dag-ink circle {
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
    animation: dag-pop .5s ease forwards;
  }
  .dag-wash { opacity: 0; animation: dag-bloom 1.2s ease forwards .75s; }

  .dag-ink line:nth-of-type(1) { animation-delay: .30s; }
  .dag-ink line:nth-of-type(2) { animation-delay: .40s; }
  .dag-ink line:nth-of-type(3) { animation-delay: .50s; }
  .dag-ink line:nth-of-type(4) { animation-delay: .60s; }
  .dag-ink line:nth-of-type(5) { animation-delay: .70s; }
  .dag-ink line:nth-of-type(6) { animation-delay: .80s; }
  .dag-ink circle:nth-of-type(1) { animation-delay: .60s; }
  .dag-ink circle:nth-of-type(2) { animation-delay: .68s; }
  .dag-ink circle:nth-of-type(3) { animation-delay: .76s; }
  .dag-ink circle:nth-of-type(4) { animation-delay: .84s; }
  .dag-ink circle:nth-of-type(5) { animation-delay: .92s; }
  .dag-ink circle:nth-of-type(6) { animation-delay: 1.00s; }
  .dag-ink circle:nth-of-type(7) { animation-delay: 1.08s; }

  @keyframes dag-draw  { to { stroke-dashoffset: 0; } }
  @keyframes dag-pop   { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: none; } }
  @keyframes dag-bloom { to { opacity: 1; } }
}

/* The hand-drawn boil (the ink redrawn a few times a second) is SMIL
   inside research.html; reduced motion is handled by the script there,
   because CSS cannot stop a SMIL animation. */

@media (max-width: 640px) { :root { --dag-size: 92px; } }

/* ============================================================
   Publications.
   Year blocks, newest first: the year sits in the left margin and
   stays there while its papers scroll past. Selectors are prefixed
   with .publications so they outrank the generic `.doc section p` rules.
   ============================================================ */

.publications { max-width: 56rem; }

.publications .year {
  display: grid;
  grid-template-columns: 6rem 1fr;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding-top: clamp(1.4rem, 3vh, 2rem);
  margin-top: clamp(1.4rem, 3vh, 2rem);
  border-top: 1px solid var(--rule);
}
.publications .year:first-of-type { border-top: 0; margin-top: clamp(.4rem, 1.5vh, 1rem); }

.publications .year h2 {
  position: sticky;
  top: 1.5rem;
  align-self: start;
  font-size: clamp(1.45rem, 2.5vw, 1.9rem);
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--muted);
}

.publications .pub-list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: clamp(1.15rem, 2.2vh, 1.6rem);
}

.publications .pub-title {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 500;
  line-height: 1.42;
  letter-spacing: -0.014em;
  color: var(--ink);
}
.publications .pub-authors {
  margin: .22rem 0 0;
  font-size: 0.845rem;
  line-height: 1.45;
  letter-spacing: -0.003em;
  color: var(--body);
}
.publications .pub-authors b { font-weight: 600; color: var(--ink); }
.publications .pub-venue {
  margin: .12rem 0 0;
  font-size: 0.815rem;
  line-height: 1.45;
  letter-spacing: -0.003em;
  color: var(--muted);
}

.publications .pub-type {
  display: inline-block;
  margin-left: .5rem;
  padding: .08rem .4rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  vertical-align: 1px;
}

@media (max-width: 640px) {
  .publications .year { grid-template-columns: 1fr; gap: .8rem; }
  .publications .year h2 { position: static; font-size: 1.3rem; }
}

/* linked titles */
.publications .pub-title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: border-color .2s ease;
}
.publications .pub-title a:hover { border-bottom-color: var(--ink); }
.publications .pub-title a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* ============================================================
   People.
   Circular portraits; the grid reflows on its own as the lab grows.
   ============================================================ */

.people .people-grid {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(2rem, 4vw, 3.2rem);
  margin-top: clamp(1.4rem, 3.5vh, 2.4rem);
}

.people .person-photo {
  display: block;
  width: clamp(120px, 46%, 168px);
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  background: #EFEAE1;
  margin-bottom: 1.15rem;
}
.people .person-photo--none {
  display: grid;
  place-items: center;
  font-size: 2.4rem;
  font-weight: 200;
  color: var(--muted);
}

.people .person-name {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.018em;
  color: var(--ink);
}
.people .person-role {
  margin: .28rem 0 0;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--body);
}
.people .person-affil {
  list-style: none;
  padding: 0;
  margin: .6rem 0 0;
}
.people .person-affil li {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted);
}

/* ============================================================
   Contact.
   Address and the invitation on the left, the photograph on the
   right; stacked when there is not room for both. The photograph
   opens enlarged in a dialog.
   ============================================================ */

.doc.contact { max-width: 64rem; }

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  gap: clamp(1.8rem, 4.5vw, 3.4rem);
  align-items: start;
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
}

/* --- the address ------------------------------------------- */

.contact .addr {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.7;
  letter-spacing: -0.004em;
  color: var(--body);
}
.contact .addr span { display: block; }
.contact .addr span:first-child { color: var(--ink); }

.contact .contact-link { margin: 1.1rem 0 0; }
.contact .contact-link a {
  font-size: 0.87rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  transition: border-color .2s ease;
}
.contact .contact-link a:hover { border-bottom-color: var(--ink); }
.contact .contact-link span { display: inline-block; margin-left: .35rem; transition: margin-left .2s ease; }
.contact .contact-link a:hover span { margin-left: .6rem; }

/* --- join the lab ------------------------------------------- */

.join {
  margin-top: clamp(2.4rem, 6vh, 3.6rem);
  padding-top: clamp(1.4rem, 3vh, 2rem);
  border-top: 1px solid var(--rule);
}
.contact .join h2 {
  margin: 0 0 .7rem;
  font-weight: 200;
  font-size: clamp(1.45rem, 2.6vw, 1.95rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-transform: none;
}
.contact .join p {
  margin: 0;
  font-size: clamp(1rem, 1.2vw, 1.08rem);
  line-height: 1.62;
  color: var(--body);
  max-width: 42ch;
}
.contact .join-mail { margin-top: 1.1rem !important; }
.contact .join-mail a {
  font-size: clamp(1rem, 1.25vw, 1.12rem);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 4px;
  transition: border-color .2s ease;
  word-break: break-word;
}
.contact .join-mail a:hover { border-bottom-color: var(--ink); }

/* --- the photograph ----------------------------------------- */

.contact-photo { margin: 0; }

.photo-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: 4px;
  transition: transform .35s cubic-bezier(.2,.7,.3,1), box-shadow .35s ease;
  box-shadow: 0 12px 34px rgba(60, 44, 30, .13), 0 0 0 1px rgba(60, 44, 30, .05);
}
.photo-btn img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}
.photo-btn:hover { transform: scale(1.012); box-shadow: 0 18px 44px rgba(60, 44, 30, .18), 0 0 0 1px rgba(60, 44, 30, .06); }
.photo-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.contact-photo figcaption {
  margin-top: .8rem;
  font-size: 0.76rem;
  letter-spacing: 0.01em;
  color: var(--muted);
}

/* --- enlarged view ------------------------------------------ */

.lightbox {
  border: 0;
  padding: 0;
  background: none;
  max-width: 90vw;
  max-height: 90vh;
  overflow: visible;
}
.lightbox::backdrop { background: rgba(28, 24, 20, .72); }
.lightbox img {
  display: block;
  max-width: 72vw;
  max-height: 74vh;
  width: auto;
  height: auto;
  border-radius: 4px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .4);
}
.lightbox figcaption {
  margin-top: .8rem;
  font-size: 0.78rem;
  text-align: center;
  color: rgba(255, 255, 255, .8);
  text-shadow: 0 1px 4px rgba(0, 0, 0, .55);
}
.lightbox figure { margin: 0; }

.lightbox-close {
  position: absolute;
  top: -2.4rem;
  right: -0.1rem;
  width: 2rem;
  height: 2rem;
  border: 0;
  padding: 0;
  background: none;
  color: rgba(255, 255, 255, .78);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: color .2s ease;
}
.lightbox-close:hover { color: #fff; }
.lightbox-close:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* open / close animation */
.lightbox, .lightbox::backdrop {
  transition: opacity .28s ease, transform .28s cubic-bezier(.2,.7,.3,1), overlay .28s allow-discrete, display .28s allow-discrete;
}
.lightbox { opacity: 0; transform: scale(.96); }
.lightbox::backdrop { opacity: 0; }
.lightbox[open] { opacity: 1; transform: scale(1); }
.lightbox[open]::backdrop { opacity: 1; }
@starting-style {
  .lightbox[open] { opacity: 0; transform: scale(.96); }
  .lightbox[open]::backdrop { opacity: 0; }
}

@media (max-width: 860px) {
  .lightbox img { max-width: 90vw; max-height: 76vh; }
  .contact-grid { grid-template-columns: 1fr; }
  .contact-photo { margin-top: 1.6rem; }
  .contact .join p { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .photo-btn, .lightbox, .lightbox::backdrop { transition: none; }
  .photo-btn:hover { transform: none; }
}

/* keep every address line unbroken on small phones */
@media (max-width: 440px) {
  .contact .addr { font-size: clamp(0.72rem, 3.5vw, 0.86rem); line-height: 1.75; }
}

/* --- the small ink DAG beside a heading ---------------------- */

#lah path { fill: var(--dag-ink); }

.contact .has-mark {
  display: flex;
  align-items: center;
  gap: .5em;
}
.dagmark {
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
  overflow: visible;
}
.dagmark .w circle { opacity: .40; }
.dagmark .i line   { stroke: var(--dag-ink); stroke-width: 2.4; stroke-linecap: round; fill: none; }
.dagmark .i circle { fill: var(--bg); stroke: var(--dag-ink); stroke-width: 2.4; }

/* hang the mark in the margin so the headings keep the text's left edge */
@media (min-width: 1140px) {
  .contact .has-mark { margin-left: calc(-1em - .5em); }
  .contact .join h2.has-mark { margin-left: calc(-1em - .5em); }
}

@media (prefers-reduced-motion: no-preference) {
  .dagmark .i line {
    stroke-dasharray: 130; stroke-dashoffset: 130;
    animation: dag-draw .9s ease forwards;
    animation-delay: calc(.2s + var(--d) * .35s);
  }
  .dagmark .i circle {
    opacity: 0;
    animation: dag-fade .6s ease forwards;
    animation-delay: calc(.55s + var(--d) * .35s);
  }
  .dagmark .w {
    opacity: 0;
    animation: dag-fade 1.4s ease forwards;
    animation-delay: calc(.85s + var(--d) * .35s);
  }
  .dagmark .w circle {
    animation: dag-sweep 15s ease-in-out infinite;
    animation-delay: calc(var(--d) * 3s);
  }
}

/* ============================================================
   News.
   Year on the left, entries on the right, newest first. Laid out
   like the publications page so the two read as one family.
   ============================================================ */

.news { max-width: 56rem; }

.news .year {
  display: grid;
  grid-template-columns: 6rem 1fr;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding-top: clamp(1.4rem, 3vh, 2rem);
  margin-top: clamp(1.4rem, 3vh, 2rem);
  border-top: 1px solid var(--rule);
}
.news .year:first-of-type { border-top: 0; margin-top: clamp(.4rem, 1.5vh, 1rem); }

.news .year h2 {
  position: sticky;
  top: 1.5rem;
  align-self: start;
  font-size: clamp(1.45rem, 2.5vw, 1.9rem);
  font-weight: 200;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--muted);
}

.news .news-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: clamp(1.15rem, 2.2vh, 1.7rem);
}

.news .news-date {
  margin: 0 0 .25rem;
  font-size: 0.735rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.news .news-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.42;
  letter-spacing: -0.014em;
  color: var(--ink);
}
.news .news-title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: border-color .2s ease;
}
.news .news-title a:hover { border-bottom-color: var(--ink); }
.news .news-source {
  margin: .28rem 0 0;
  font-size: 0.79rem;
  letter-spacing: -0.003em;
  color: var(--muted);
}
.news .news-empty { color: var(--muted); }

@media (max-width: 620px) {
  .news .year { grid-template-columns: 1fr; gap: .9rem; }
  .news .year h2 { position: static; }
}
