@font-face {
  font-family: Inter;
  src: url('../fonts/inter-latin.v1.0.0.woff2') format('woff2');
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
}
/* Light theme. Every colour below derives from these tokens; the dark intro
   keeps its own explicit colours further down. */
:root {
  color-scheme: light;
  --bg: #ffffff;
  --surface: #f5f7fa;
  --surface-strong: #edf1f6;
  --tint: #eaf0fa;
  --text: #16191d;
  --body: #363c46;
  --muted: #4f5662;
  --faint: #646b77;
  --accent: #2554a3;
  --accent-strong: #173f80;
  --blue: #3a6cc0;
  --line: #e4e8ee;
  --line-strong: #cfd6df;
  --intro-bg: var(--bg);
  --font: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}
* { box-sizing: border-box; }
/* touch-action: manipulation answers every tap at once (no wait for a possible
   double-tap zoom), so quick successive taps all register; pinch zoom still works. */
html { background: var(--bg); scrollbar-gutter: stable; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
body { margin: 0; background: var(--bg); color: var(--text); font: 400 16px/1.75 var(--font); -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4, h5, p { margin: 0; }
h1, h2, h3, h4, h5 { font-weight: 500; }
strong { font-weight: 600; }
a { color: inherit; text-decoration: none; }
@media (hover: hover) { a:hover { color: var(--accent); } }
a.is-clicked { color: var(--link-rest, var(--text)) !important; }
button, input, textarea { font: inherit; }
a, button { touch-action: manipulation; }
button, summary { cursor: pointer; }
img { display: block; max-width: 100%; height: auto; }
[hidden] { display: none !important; }
a:focus-visible, button:focus-visible, summary:focus-visible, input:focus-visible, textarea:focus-visible, [tabindex="0"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
::selection { color: var(--text); background: #cddcf5; }
.skip-link { position: fixed; top: 12px; left: 12px; z-index: 100; padding: 10px 20px; background: var(--bg); border: 1px solid var(--blue); border-radius: 10px; transform: translateY(-180%); }
.skip-link:focus { transform: none; }
.site-shell { max-width: 1070px; margin: auto; padding: 0 56px; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
.site-header { padding: 56px 0 24px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.identity { display: inline-flex; align-items: center; min-height: 44px; --link-rest: var(--text); }
h1, .wordmark { font-family: var(--mono); font-size: 22px; font-weight: 400; letter-spacing: -.7px; line-height: 1.6; text-transform: none; }
.workspace { display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 48px; padding: 36px 0 52px; flex: 1; align-items: start; }
.sidebar { position: sticky; top: 40px; }
.section-nav { display: flex; flex-direction: column; border-left: 0; }
.section-nav a { position: relative; display: flex; align-items: center; min-height: 40px; padding: 6px 0 6px 19px; font-size: 15px; color: var(--muted); }
.section-nav a::before { content: ''; position: absolute; left: 0; top: 7px; bottom: 7px; width: 1px; background: var(--line-strong); }
.section-nav a[aria-current='page'] { color: var(--accent); font-weight: 500; }
.section-nav a[aria-current='page']::before { width: 2px; background: var(--blue); }
.section-nav a:focus-visible { color: var(--accent); }
@media (hover: hover) { .section-nav a:hover { color: var(--accent); } }
.nav-icon { display: none; }
main { min-width: 0; outline: none; }
#page-title:focus, .panel h2:focus { outline: none; }
.panel + .panel { margin-top: 64px; }
.is-enhanced .panel + .panel { margin-top: 0; }
.panel > h2 { font-size: 30px; line-height: 1.35; font-weight: 300; letter-spacing: -.6px; margin-bottom: 12px; color: var(--text); }
#about { max-width: 640px; margin-inline: auto; }
.about-intro { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 36px; align-items: center; margin-bottom: 32px; }
.hero-title { font-size: 38px; font-weight: 400; line-height: 1.22; letter-spacing: -1px; color: var(--text); }
.portrait { order: -1; width: 160px; height: 160px; object-fit: cover; object-position: 50% 32%; border-radius: 14px; }
.prose { color: var(--body); font-size: 16.5px; line-height: 1.8; }
.prose p + p { margin-top: 20px; }
.prose strong { color: var(--text); }
.prose a { --link-rest: var(--accent); color: var(--accent); text-decoration: underline; text-decoration-color: rgba(37, 84, 163, .35); text-underline-offset: 4px; }
@media (hover: hover) { .prose a:hover { color: var(--accent-strong); text-decoration-color: currentColor; } }
.about-copy .person-link { white-space: nowrap; }
.prose p { text-wrap: pretty; }
.personal-note { color: var(--muted); }
.group-label, .publication-group-heading { color: var(--text); font-size: 12px; font-weight: 600; letter-spacing: .9px; text-transform: uppercase; }
.group-label { margin: 26px 0 8px; }
.timeline-row { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 18px; padding: 8px 0; }
.timeline-date { color: var(--muted); font-size: 13.5px; font-variant-numeric: tabular-nums; }
.timeline-row h4 { font-size: 16.5px; line-height: 1.55; color: var(--text); }
.timeline-row h4 a { --link-rest: var(--text); }
.timeline-row h4 a span { color: var(--accent); }
.timeline-row p { color: var(--muted); font-size: 14.5px; margin-top: 2px; }
.row-note { display: block; font-size: 13.5px; color: var(--faint); margin-top: 2px; }
.project-list { overflow-anchor: none; }
.project { border-top: 1px solid var(--line); scroll-margin-top: 25px; }
.project:last-of-type { border-bottom: 1px solid var(--line); }
.project[open] { background: var(--surface); border-radius: 12px; border-top-color: transparent; }
.project[open] + .project { border-top-color: transparent; }
.project summary { list-style: none; display: grid; grid-template-columns: minmax(0, 1fr) 24px; grid-template-areas: "title toggle" "meta toggle" "description toggle"; column-gap: 12px; row-gap: 1px; padding: 12px 16px; border-radius: 12px; }
.project summary::-webkit-details-marker { display: none; }
.project summary::marker { content: ''; }
@media (hover: hover) { .project summary:hover { background: var(--surface); } }
.project summary > h4 { grid-area: title; font-size: 17px; line-height: 1.5; color: var(--text); }
.project summary > .project-meta { grid-area: meta; }
.project summary > .project-tldr { grid-area: description; }
.project-tldr { margin: 2px 0 0; color: var(--muted); font-size: 14.5px; line-height: 1.5; }
.project-tldr strong, .publication-description strong { color: var(--text); }
.project-meta { display: block; font-size: 13px; line-height: 1.7; color: var(--faint); }
.project[open] summary h4 { color: var(--accent); }
@media (hover: hover) { .project summary:hover h4 { color: var(--accent); } }
.project-toggle { grid-area: toggle; color: var(--accent); font-size: 21px; align-self: center; text-align: center; }
.project-toggle::before { content: '+'; }
.project[open] .project-toggle::before { content: '−'; }
.project-body { color: var(--body); font-size: 16px; line-height: 1.75; padding: 4px 16px 20px; overflow-wrap: break-word; }
.project-body p { margin-bottom: 10px; }
.project-body strong { color: var(--text); }
.project-body figure { margin: 18px 0; }
.project-body figure img { width: 100%; height: auto; background: #fff; border: 1px solid var(--line); border-radius: 8px; }
.project-body figcaption { font-size: 13px; line-height: 1.6; color: var(--muted); margin-top: 6px; }
.project-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; }
.project-links { display: flex; gap: 12px 24px; flex-wrap: wrap; }
.text-link { --link-rest: var(--accent); color: var(--accent); font-size: 13.5px; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; }
@media (hover: hover) { .text-link:hover { color: var(--accent-strong); } }
.publication { padding: 6px 0 8px; }
.publication + .publication { margin-top: 2px; }
.publication-group-heading { margin: 40px 0 12px; line-height: 1.5; scroll-margin-top: 30px; }
.publication h3, .publication h4 { font-size: 16px; line-height: 1.45; margin: 2px 0 3px; color: var(--text); }
.publication h3 a, .publication h4 a { --link-rest: var(--text); }
.publication h3 a span, .publication h4 a span { color: var(--accent); white-space: nowrap; }
.publication-authors { font-size: 14.5px; line-height: 1.6; color: var(--muted); }
.publication-authors strong { color: var(--text); }
.publication .publication-authors { font-size: 13.5px; }
.publication-authors sup { font-size: 10.5px; margin-left: 1px; }
/* Co-first-author mark: full-weight, text-coloured asterisk. The glyph already sits high, so it is only nudged up. */
.publication-authors .cofirst, .research-authors .cofirst { color: var(--text); font-size: 15px; font-weight: 700; line-height: 0; vertical-align: .1em; }
.publication-description { font-size: 14.5px; line-height: 1.55; color: var(--muted); margin: 5px 0 0; }
.publication-group-heading:focus, .research-item:focus { outline: none; }
/* Research filters: Selected, Publications, Projects, Notes. Without JS every
   group renders and the links are ordinary in-page anchors. */
.research-filters { display: flex; flex-wrap: wrap; gap: 16px 6px; margin: 2px 0 20px -9px; }
.research-filters a { --link-rest: var(--muted); position: relative; display: inline-flex; align-items: center; min-height: 28px; padding: 2px 9px; border-radius: 999px; color: var(--muted); font-size: 14.5px; font-weight: 500; line-height: 1.4; }
@media (hover: hover) { .research-filters a:hover { color: var(--accent); background: var(--surface); } }
.research-filters a[aria-current='true'] { --link-rest: var(--accent); color: var(--accent); background: var(--tint); }
.research-group { scroll-margin-top: 30px; }
.research-group:focus { outline: none; }
.is-enhanced .research-group > .publication-group-heading { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.group-description { margin: 0 0 14px; color: var(--muted); font-size: 15px; }
/* Research cards (homepage) */
.research-item { padding: 16px 0; scroll-margin-top: 25px; }
.research-item:first-child { padding-top: 2px; }
.research-venue { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 13px; line-height: 1.7; color: var(--faint); }
.badge { display: inline-block; padding: 0 8px; border-radius: 999px; background: var(--tint); color: #1f4b94; font-size: 10.5px; font-weight: 600; line-height: 20px; letter-spacing: .7px; text-transform: uppercase; }
.badge.is-award { background: var(--accent); color: #fff; }
.research-item h4 { font-size: 18px; font-weight: 600; line-height: 1.4; letter-spacing: -.2px; margin: 4px 0 4px; color: var(--text); text-wrap: pretty; }
.research-item h4 a { --link-rest: var(--text); }
.research-links { display: flex; flex-wrap: wrap; gap: 12px 20px; margin-top: 6px; }
.research-link { --link-rest: var(--accent); display: inline-flex; align-items: center; gap: 6px; min-height: 32px; color: var(--accent); font-size: 14px; font-weight: 500; }
.research-link:focus-visible { color: var(--accent-strong); text-decoration: underline; text-underline-offset: 4px; }
@media (hover: hover) { .research-link:hover { color: var(--accent-strong); text-decoration: underline; text-underline-offset: 4px; } }
.research-link svg, .back-link svg, .copy-button svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.research-link svg.brand { fill: currentColor; stroke: none; }
.resource { display: block; padding: 12px 0; }
.resource h4 { font-size: 17px; line-height: 1.55; margin: 5px 0; color: var(--text); }
.resource h4 span { color: var(--accent); }
.resource p { font-size: 15px; color: var(--muted); }
#contact-form { margin-top: 28px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.field label { font-size: 13.5px; font-weight: 500; color: var(--body); }
input, textarea { width: 100%; min-width: 0; font-size: 16px; line-height: 1.5; padding: 7px 11px; color: var(--text); background: var(--bg); border: 1px solid var(--line-strong); border-radius: 10px; }
input::placeholder, textarea::placeholder { color: #7a828e; }
textarea { resize: vertical; min-height: 112px; }
@media (hover: hover) { input:hover, textarea:hover { border-color: #aab3bf; } }
.button { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 34px; gap: 6px; padding: 4px 12px; border: 1px solid var(--accent); border-radius: 10px; color: #fff; background: var(--accent); font-size: 14px; font-weight: 500; }
@media (hover: hover) { .button:hover { color: #fff; background: var(--accent-strong); border-color: var(--accent-strong); } }
.button:disabled { cursor: wait; opacity: .65; }
/* Touch targets: small controls keep a compact look but get an invisible hit
   area of at least 44px tall, so a tap just beside them still lands. The
   extensions never reach the neighbouring control. */
.research-link, .back-link, .copy-button, .contact-email, .profile-link { position: relative; }
.research-link::after { content: ''; position: absolute; inset: -6px -9px; }
.research-filters a::after { content: ''; position: absolute; inset: -8px -3px; }
.button::after, .copy-button::after { content: ''; position: absolute; inset: -6px -6px; }
.form-honeypot { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.gtm-noscript { display: none; visibility: hidden; border: 0; }
.viewport-edge, .viewport-top { display: none; }
.form-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 15px; }
.contact-email { display: inline-flex; align-items: center; min-height: 44px; gap: 7px; color: var(--accent); font-size: 13.5px; }
.form-verification { line-height: 0; }
.form-verification.is-interactive { margin-bottom: 18px; }
.form-note { margin-top: 18px; font-size: 13px; color: var(--muted); }
#form-status { font-size: 13px; color: var(--accent); margin-top: 18px; }
.site-footer { border-top: 0; display: flex; justify-content: center; align-items: center; gap: 20px; padding: 24px 0; font-size: 12.5px; color: var(--faint); }
/* intro-pending is set by the inline head bootstrap before first paint and
   cleared when the deferred intro starts (or at DOMContentLoaded/timeout). */
html.intro-active, html.intro-pending { background: var(--intro-bg); }
.intro-active, .intro-pending { overflow: hidden; }
/* During the intro the page is covered, not hidden: it paints from the first
   frame under an opaque layer, so the browser counts the content as rendered
   (Largest Contentful Paint) instead of waiting for the entrance to finish.
   intro.js keeps it inert and aria-hidden until then. */
html.intro-active::after, html.intro-pending::after { content: ''; position: fixed; inset: 0; z-index: 49; background: var(--intro-bg); }
.intro-active .skip-link, .intro-pending .skip-link { display: none; }
#intro { --intro-diameter: min(380px, calc(100vw - 40px), calc(100svh - 40px)); position: fixed; inset: 0; z-index: 50; background: var(--intro-bg); touch-action: none; }
/* The WebGL simulation draws light particles; inverting the canvas turns them
   into ink on the light page without touching the shaders. */
#canvas { position: absolute; inset: auto; top: 50%; left: 50%; transform: translate(-50%, -50%); pointer-events: none; filter: invert(1); }
#preloader-text { position: absolute; top: 50%; left: 0; width: 100%; text-align: center; transform: translateY(-50%); opacity: 0; padding: 24px; pointer-events: none; z-index: 2; }
#preloader-text-title { color: var(--text); font-family: var(--mono); font-size: 28px; line-height: 1.7; letter-spacing: 1px; text-transform: none; padding-left: 1px; }
#preloader-text-author { font-size: 13px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--muted); margin-top: 8px; opacity: 0; }
#intro.intro-static::before { content: ''; position: absolute; width: var(--intro-diameter); aspect-ratio: 1; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 1px solid var(--line-strong); border-radius: 50%; box-shadow: 0 0 24px rgba(37, 84, 163, .07), inset 0 0 24px rgba(37, 84, 163, .07); }
#intro.intro-static #canvas { display: none; }
#intro-circle { -webkit-appearance: none; appearance: none; position: absolute; z-index: 1; width: var(--intro-diameter); height: var(--intro-diameter); left: 50%; top: 50%; transform: translate(-50%, -50%); border: 0; border-radius: 50%; padding: 0; background: transparent; }
#intro-circle:focus-visible { outline: 1px solid var(--blue); outline-offset: 12px; }
#intro.intro-static.intro-leaving::before { transform: translate(-50%, -50%) scale(1.22); opacity: 0; transition: transform .55s ease, opacity .55s ease; }
#intro.intro-static.intro-leaving #preloader-text { opacity: 0 !important; transition: opacity .35s ease; }
.header-links { display: flex; align-items: center; gap: 20px; }
.profile-link { --link-rest: var(--muted); display: inline-flex; align-items: center; gap: 9px; min-height: 44px; color: var(--muted); font-size: 13.5px; }
.profile-link svg, .nav-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.profile-link:focus-visible { color: var(--accent); }
@media (hover: hover) { .profile-link:hover { color: var(--accent); } }
/* Icon-only links keep a 24px-wide target (WCAG 2.5.8). */
.profile-link.icon-only { min-width: 24px; justify-content: center; }

/* Research pages: an article inside the normal site layout. */
.research-article { max-width: 720px; }
.not-found-text { margin: 0 0 14px; color: var(--body); font-size: 16px; line-height: 1.7; }
.back-link { --link-rest: var(--muted); display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: -8px 0 6px; color: var(--muted); font-size: 14px; }
.research-title { margin: 6px 0 12px; font-family: var(--font); font-size: 30px; font-weight: 400; line-height: 1.3; letter-spacing: -.5px; color: var(--text); text-align: left; text-wrap: balance; }
.research-authors { font-size: 15px; line-height: 1.6; color: var(--muted); }
.research-authors strong { color: var(--text); }
.research-authors sup, .research-affiliations sup { margin-left: 1px; font-size: 10.5px; }
.research-affiliations { margin-top: 2px; font-size: 13.5px; line-height: 1.6; color: var(--faint); }
.research-article .research-links { margin-top: 10px; }
.research-tldr { margin: 26px 0 30px; padding: 16px 18px; border-radius: 12px; background: var(--surface); color: var(--body); font-size: 16.5px; line-height: 1.7; }
.research-tldr strong { color: var(--text); }
.research-article h2 { margin: 44px 0 12px; color: var(--text); font-size: 22px; font-weight: 500; line-height: 1.35; letter-spacing: -.3px; scroll-margin-top: 30px; }
.research-article .prose ul, .research-article .prose ol { margin: 14px 0; padding-left: 22px; }
.research-article .prose li { margin: 6px 0; padding-left: 3px; }
.research-figure { margin: 28px 0; }
.research-figure img { width: 100%; height: auto; background: #fff; }
.research-figure figcaption { margin-top: 10px; color: var(--muted); font-size: 14px; line-height: 1.6; }
.research-figure figcaption strong { color: var(--text); }
.stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 18px 0 10px; }
.stat { margin: 0; padding: 11px 14px; border-radius: 10px; background: var(--surface); }
.stat-value { display: block; color: var(--accent); font-size: 24px; font-weight: 500; line-height: 1.15; letter-spacing: -.6px; font-variant-numeric: tabular-nums; }
.stat-label { display: block; margin-top: 3px; color: var(--muted); font-size: 13.5px; line-height: 1.45; }
.table-scroll { margin: 18px 0 10px; overflow-x: auto; }
.research-table { margin: 18px 0 10px; }
.research-table .table-scroll { margin: 0; }
.research-table figcaption { margin-top: 10px; }
.data-table { width: 100%; min-width: 500px; border-collapse: collapse; font-size: 14.5px; line-height: 1.5; font-variant-numeric: tabular-nums; }
.data-table th, .data-table td { padding: 8px 10px; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
.data-table th:first-child, .data-table td:first-child { padding-left: 0; text-align: left; }
.data-table th { color: var(--muted); font-size: 12.5px; font-weight: 500; }
.data-table td { color: var(--body); }
.data-table tbody th { color: var(--text); font-size: 14.5px; }
.data-table tr.is-highlight th, .data-table tr.is-highlight td { background: var(--tint); color: var(--text); font-weight: 600; }
.data-table tr.is-highlight th { padding-left: 8px; border-radius: 6px 0 0 6px; }
.data-table tr.is-highlight td:last-child { border-radius: 0 6px 6px 0; }
.data-table.is-text { min-width: 560px; }
.data-table.is-text th, .data-table.is-text td { text-align: left; white-space: normal; vertical-align: top; }
.data-table th[scope="rowgroup"] { padding: 16px 0 6px; color: var(--faint); font-size: 11.5px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; text-align: left; }
.data-table tbody:first-of-type th[scope="rowgroup"] { padding-top: 10px; }
.th-sub { display: block; margin-top: 1px; color: var(--faint); font-size: 12.5px; font-weight: 400; letter-spacing: 0; text-transform: none; white-space: normal; }
.data-table.is-fit { min-width: 0; }
.data-table.is-fit thead th { vertical-align: bottom; white-space: normal; }
.data-table.is-grid { min-width: 460px; }
.data-table.is-grid thead th { vertical-align: bottom; }
.data-table.is-grid tbody th { font-weight: 600; }
.data-table tfoot th, .data-table tfoot td { border-bottom: 0; padding-top: 10px; color: var(--text); }
.data-table tfoot th { font-size: 14.5px; font-weight: 600; }
/* Phones: tighter cells so the results tables fit without sideways scrolling. */
@media (max-width: 560px) {
  .data-table { font-size: 13.5px; }
  .data-table th, .data-table td { padding: 7px 6px; }
  .data-table tbody th, .data-table tfoot th { font-size: 13.5px; }
  .data-table .th-sub { font-size: 12px; }
  .data-table.is-grid { min-width: 0; }
  .data-table .sd { display: block; color: var(--faint); font-size: 12px; font-weight: 400; }
}
@media (max-width: 360px) {
  .data-table { font-size: 13px; }
  .data-table th, .data-table td { padding: 7px 3px; }
  .data-table tbody th, .data-table tfoot th { font-size: 13px; }
  .data-table thead th { font-size: 11.5px; }
  .data-table .th-sub { font-size: 11.5px; }
}
.table-note { color: var(--faint); font-size: 13.5px; line-height: 1.6; }
.poster-preview { display: block; max-width: 320px; margin: 18px 0 10px; }
.poster-preview img { width: 100%; height: auto; border-radius: 8px; box-shadow: 0 1px 3px rgba(20, 30, 50, .12), 0 8px 24px rgba(20, 30, 50, .08); }
.citation-block { position: relative; margin-top: 14px; }
.citation { margin: 0; padding: 16px 18px; overflow-x: auto; border-radius: 12px; background: var(--surface); color: #24292f; font: 13px/1.7 var(--mono); white-space: pre; }
.copy-button { position: absolute; top: 10px; right: 10px; display: inline-flex; align-items: center; min-height: 32px; padding: 4px 11px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--bg); color: var(--body); font-size: 12.5px; font-weight: 500; }
@media (hover: hover) { .copy-button:hover { border-color: var(--accent); color: var(--accent); } }
/* Figures sized to their content; compact charts never fill the column. */
.research-figure.is-medium { max-width: 600px; margin-inline: auto; }
.research-figure.is-narrow { max-width: 400px; margin-inline: auto; }
.research-venue + .research-venue { margin-top: 4px; }
/* In-text citations and the reference list. */
.cite { margin-left: 1px; font-size: .68em; line-height: 0; vertical-align: super; }
.cite a { --link-rest: var(--accent); position: relative; color: var(--accent); font-weight: 500; text-decoration: none; }
.cite a::after { content: ''; position: absolute; inset: -15px -3px; }
.references { margin: 0; padding: 0; list-style: none; counter-reset: ref; color: var(--muted); font-size: 14px; line-height: 1.6; overflow-wrap: anywhere; }
/* Numbers are drawn inside each item, so the highlight covers them too. */
.references li { position: relative; margin: 7px 0; padding-left: 32px; border-radius: 6px; counter-increment: ref; scroll-margin-top: 40vh; box-shadow: 0 0 0 6px transparent; transition: background-color .45s ease, box-shadow .45s ease, color .45s ease; }
.references li::before { content: counter(ref) "."; position: absolute; top: 0; left: 0; width: 24px; color: var(--faint); font-variant-numeric: tabular-nums; text-align: right; transition: color .45s ease; }
/* A cited reference lights up on arrival, then fades after 0.7 s (article.v1.0.0.js). */
.references li.is-flash { background: var(--tint); box-shadow: 0 0 0 6px var(--tint); color: var(--text); transition: none; }
.references li.is-flash::before { color: var(--accent); font-weight: 600; transition: none; }
.references a { color: var(--accent); }
/* Enlargeable figures (article.v1.0.0.js): tap or click opens a modal dialog. */
.figure-zoom { display: block; width: 100%; margin: 0; padding: 0; border: 0; border-radius: 6px; background: none; cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
.figure-zoom img { display: block; }
.figure-zoom:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.figure-zoom.is-quiet:focus-visible { outline: none; }
html.lightbox-open { overflow: hidden; }
.lightbox { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; color: var(--body); overflow: hidden; }
.lightbox::backdrop { background: #fff; }
.lightbox { cursor: zoom-out; }
.lightbox:focus { outline: none; }
.lightbox[open] { animation: lightbox-in .16s ease-out; }
.lightbox[open]::backdrop { animation: lightbox-fade .16s ease-out; }
@keyframes lightbox-in { from { opacity: 0; transform: scale(.985); } }
@keyframes lightbox-fade { from { opacity: 0; } }
/* Wide screens keep a generous margin to click; phones keep a tappable edge. */
.lightbox-panel { display: flex; box-sizing: border-box; width: 100%; height: 100%; padding: 80px max(48px, 8vw) 56px; overflow: auto; overscroll-behavior: contain; }
@media (max-width: 760px) {
  .lightbox-panel { padding: max(72px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(32px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left)); }
}
.lightbox-figure { display: flex; flex-direction: column; align-items: center; gap: 14px; margin: auto; }
.lightbox-figure img { display: block; max-width: 100%; height: auto; border-radius: 8px; background: #fff; box-shadow: 0 1px 3px rgba(20, 30, 50, .1), 0 12px 40px rgba(20, 30, 50, .12); }
.lightbox-figure figcaption { max-width: 720px; color: var(--muted); font-size: 14px; line-height: 1.6; }
.lightbox-figure figcaption strong { color: var(--text); }
/* Reading progress: a plain blue dot moving down a thin track on wide screens,
   a thin top line on phones. */
.read-progress { --progress: 0; position: fixed; z-index: 20; top: 50%; right: max(20px, calc((100vw - 1070px) / 2 + 18px)); width: 8px; height: min(300px, 46vh); background: linear-gradient(var(--line), var(--line)) center / 2px 100% no-repeat; transform: translateY(-50%); pointer-events: none; }
.read-progress::before { content: ''; position: absolute; top: 0; left: 3px; width: 2px; height: calc(var(--progress) * 100%); border-radius: 2px; background: var(--blue); }
.read-progress::after { content: ''; position: absolute; left: 0; top: calc(var(--progress) * 100%); width: 8px; height: 8px; border-radius: 50%; background: var(--accent); transform: translateY(-50%); }

@media (min-width: 1000px) and (min-height: 800px) {
  .site-header { padding-top: 72px; }
  .workspace { padding-top: 44px; }
}
@media (max-width: 920px) and (min-width: 761px) {
  .site-shell { padding: 0 48px; }
  .workspace { grid-template-columns: 120px minmax(0, 1fr); gap: 36px; }
  .header-links { gap: 17px; }
  .about-intro { grid-template-columns: 132px minmax(0, 1fr); gap: 26px; }
  .portrait { width: 132px; height: 132px; }
  .hero-title { font-size: 32px; }
  .identity { min-width: 0; }
  h1, .wordmark { font-size: 20px; letter-spacing: -.7px; }
}
@media (max-width: 760px), (max-width: 920px) and (pointer: coarse) {
  /* Keep keyboard focus clear of the fixed bottom navigation (WCAG 2.4.11). */
  html { scroll-padding-bottom: calc(108px + env(safe-area-inset-bottom)); }
  .site-shell { max-width: 610px; padding: 0 max(44px, env(safe-area-inset-right)) calc(108px + env(safe-area-inset-bottom)) max(44px, env(safe-area-inset-left)); }
  /* Below the floating tab bar: a solid white strip (.viewport-edge, a real
     element) on the bottom edge up to the bar, plus a short fade above it. No
     blur, so the bar and its edges stay crisp. iOS Safari extends the colour of
     a fixed, hit-testable element touching the bottom edge behind its floating
     toolbar, so text never shows through there; decorative pseudo-elements
     with pointer-events: none are ignored for that. */
  .viewport-edge { display: block; position: fixed; z-index: 25; right: 0; bottom: 0; left: 0; height: calc(70px + env(safe-area-inset-bottom)); background-color: var(--bg); }
  /* Top of every page: near-solid white at the edge and a frosted blur that
     fades out downward, so text dissolves as it scrolls up to the top. */
  .viewport-edge::before { content: ''; position: fixed; top: 0; right: 0; left: 0; height: 56px; height: calc(env(safe-area-inset-top, 0px) + 56px); background: linear-gradient(180deg, #fff 0, #fff 20px, rgba(255, 255, 255, .72) 56%, rgba(255, 255, 255, .25) 80%, rgba(255, 255, 255, 0) 100%); background: linear-gradient(180deg, #fff 0, #fff calc(env(safe-area-inset-top, 0px) + 20px), rgba(255, 255, 255, .72) 56%, rgba(255, 255, 255, .25) 80%, rgba(255, 255, 255, 0) 100%); -webkit-backdrop-filter: blur(10px) saturate(160%); backdrop-filter: blur(10px) saturate(160%); -webkit-mask-image: linear-gradient(180deg, #000 0, #000 40%, transparent 100%); mask-image: linear-gradient(180deg, #000 0, #000 40%, transparent 100%); pointer-events: none; }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .viewport-edge::before { background: linear-gradient(180deg, #fff 0, rgba(255, 255, 255, .9) 40%, rgba(255, 255, 255, 0) 100%); }
  }
  @media (prefers-reduced-transparency: reduce) {
    .viewport-edge::before { background: linear-gradient(180deg, #fff 0, #fff 45%, rgba(255, 255, 255, 0) 100%); -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
  /* At the very top of a page the fade would dim the header, so it appears
     only once the page has moved (nav.v1.0.0.js sets is-scrolled on the first
     scroll frame; a scroll-linked animation lagged behind fast flicks). */
  .viewport-edge::before { opacity: 0; }
  html.is-scrolled .viewport-edge::before { opacity: 1; }
  body::before { content: ''; position: fixed; z-index: 25; right: 0; left: 0; bottom: calc(70px + env(safe-area-inset-bottom)); height: 34px; background: linear-gradient(0deg, var(--bg), rgba(255, 255, 255, 0)); pointer-events: none; }
  /* The same at the top: a solid white strip (.viewport-top, a real element)
     fixed to the top edge, always shown, so iOS Safari fills the area behind
     its status bar with the page colour and text never shows above the
     progress line, however fast the page is flicked. Safari ignores pinned
     elements 10px tall or less for this, so it is 20px: still clear of the
     header at rest. The fade and the progress line sit on top of it. */
  .viewport-top { display: block; position: fixed; z-index: 25; top: 0; right: 0; left: 0; height: 20px; height: calc(env(safe-area-inset-top, 0px) + 20px); background-color: var(--bg); }
  html.intro-active body::before, html.intro-pending body::before, html.intro-active .viewport-edge, html.intro-pending .viewport-edge, html.intro-active .viewport-top, html.intro-pending .viewport-top { display: none; }
  .site-header { display: grid; grid-template-columns: 1fr; justify-items: center; padding: 20px 0 12px; gap: 6px; }
  .identity { justify-content: center; }
  h1, .wordmark { font-size: 25px; letter-spacing: -.7px; text-align: center; }
  .header-links { justify-content: center; gap: 17px; }
  .profile-link:not(.resume-link) { width: 44px; justify-content: center; }
  .profile-link:not(.resume-link) .profile-label { display: none; }
  .profile-link svg { width: 19px; height: 19px; }
  .profile-link, .profile-link.resume-link { font-size: 13.5px; gap: 4px; }
  .workspace { display: block; padding: 18px 0 22px; }
  .sidebar { position: static; }
  /* Floating light-glass tab bar. */
  .section-nav { position: fixed; z-index: 30; left: 50%; bottom: calc(10px + env(safe-area-inset-bottom)); width: min(440px, calc(100% - 24px)); transform: translateX(-50%); display: grid; grid-template-columns: repeat(4, 1fr); padding: 5px; border: 1px solid rgba(20, 30, 50, .09); border-radius: 999px; background: rgba(255, 255, 255, .9); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .95), 0 2px 10px rgba(20, 30, 50, .06); -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%); }
  .section-nav a { z-index: 1; flex-direction: column; justify-content: center; gap: 3px; min-height: 54px; padding: 7px 0 6px; border-radius: 999px; font-size: 11px; line-height: 1.3; letter-spacing: .1px; color: #3d4450; }
  .section-nav a[aria-current='page'] { color: var(--accent); background: rgba(37, 84, 163, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9); }
  .section-nav a:focus-visible { outline-offset: -3px; }
  #intro { --intro-diameter: min(300px, calc(100vw - 40px), calc(100svh - 40px)); }
  .section-nav .nav-icon { display: block; width: 19px; height: 19px; }
  .section-nav a::before { display: none; }
  /* Glass rim: a 1px gradient edge, brightest at the top, faint at the bottom. */
  .section-nav::before { content: ''; position: absolute; inset: -1px; padding: 1px; border-radius: inherit; background: linear-gradient(170deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, .4) 38%, rgba(20, 30, 50, .06) 64%, rgba(255, 255, 255, .7)); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); pointer-events: none; }
  /* While reading (scrolling down) the bar condenses to icons; scrolling up restores it. */
  .section-nav { transition: width .38s cubic-bezier(.3, .9, .3, 1); }
  .section-nav a { transition: min-height .38s cubic-bezier(.3, .9, .3, 1), padding .38s cubic-bezier(.3, .9, .3, 1), gap .38s ease; }
  .section-nav a span { max-height: 1.4em; overflow: hidden; transition: opacity .2s ease, max-height .3s ease; }
  .nav-compact .section-nav { width: min(280px, calc(100% - 24px)); }
  .nav-compact .section-nav a { min-height: 44px; padding: 0; gap: 0; }
  .nav-compact .section-nav a span { max-height: 0; opacity: 0; }
  .about-intro { grid-template-columns: 120px minmax(0, 1fr); gap: 18px; margin-bottom: 22px; }
  .hero-title { font-size: 30px; letter-spacing: -.8px; line-height: 1.22; text-align: left; }
  .portrait { width: 120px; height: 120px; }
  #about { max-width: 420px; }
  .prose, .project-body { font-size: 16px; line-height: 1.72; }
  .prose p + p { margin-top: 18px; }
  .personal-note { font-size: 15px; }
  .panel > h2 { font-size: 29px; }
  .timeline-row { grid-template-columns: 1fr; gap: 1px; padding: 8px 0; }
  .timeline-date { line-height: 1.5; }
  .timeline-row h4 { font-size: 16px; line-height: 1.45; }
  .timeline-row p, .row-note { font-size: 14px; line-height: 1.55; margin-top: 1px; }
  .project summary { padding: 10px; column-gap: 10px; }
  .project-meta { font-size: 13px; line-height: 1.45; }
  .project summary > h4 { font-size: 17px; line-height: 1.35; }
  .project-tldr { line-height: 1.45; }
  .project-body { padding: 2px 10px 16px; line-height: 1.65; }
  .project-body p { margin-bottom: 8px; }
  .project-body figure { margin: 14px 0; }
  .project-body figcaption { font-size: 12.5px; margin-top: 5px; }
  .publication h3, .publication h4 { line-height: 1.4; margin: 2px 0 3px; }
  .publication-authors { line-height: 1.5; }
  .publication-description { line-height: 1.45; margin-top: 4px; }
  .form-row { grid-template-columns: 1fr; gap: 0; }
  .resource { padding: 10px 0; }
  .resource h4 { font-size: 16px; line-height: 1.4; margin: 3px 0; }
  .resource p { line-height: 1.55; }
  .site-footer { justify-content: center; padding: 14px 0; font-size: 12.5px; }
  #preloader-text-title { font-size: 22px; letter-spacing: 1.4px; padding-left: 1.4px; }
  #preloader-text-author { font-size: 11.5px; letter-spacing: 1.5px; }
}
@media (max-width: 760px), (max-width: 920px) and (pointer: coarse) {
  /* Where :has() exists, one glass lens glides to the current tab. */
  @supports selector(:has(*)) {
    .section-nav::after { content: ''; position: absolute; top: 5px; bottom: 5px; left: 5px; width: calc((100% - 10px) / 4); border-radius: 999px; background: rgba(37, 84, 163, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 1px 4px rgba(20, 30, 50, .1); transform: translateX(calc(var(--nav-index, 0) * 100%)); transition: transform .26s cubic-bezier(.2, .8, .2, 1); }
    .section-nav:not(:has([aria-current='page']))::after { opacity: 0; }
    .section-nav:has(a:nth-child(2)[aria-current='page']) { --nav-index: 1; }
    .section-nav:has(a:nth-child(3)[aria-current='page']) { --nav-index: 2; }
    .section-nav:has(a:nth-child(4)[aria-current='page']) { --nav-index: 3; }
    .section-nav a[aria-current='page'] { background: transparent; box-shadow: none; }
    /* Dragging along the bar (nav.v1.0.0.js): the lens follows the finger. */
    .section-nav.is-dragging::after { opacity: 1; transform: translateX(var(--nav-drag, 0px)) scale(1.04); transition: none; }
    .section-nav.is-dragging a[aria-current='page'] { color: #3d4450; }
    .section-nav.is-dragging a.is-target { color: var(--accent); }
  }
  /* Horizontal drags stay on the bar; vertical swipes still scroll the page. */
  .section-nav { touch-action: pan-y; -webkit-user-select: none; user-select: none; }
  .section-nav a { -webkit-touch-callout: none; }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .section-nav { background: rgba(250, 251, 253, .97); }
  }
  @media (prefers-reduced-transparency: reduce) {
    .section-nav { background: #f4f6f9; -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
  .research-item { padding: 14px 0; }
  /* Research pages */
  /* Project pages: the progress line sits on the shared top fade below. */
  .read-progress { z-index: 26; top: env(safe-area-inset-top, 0px); right: 0; left: 0; width: auto; height: 2px; background: none; transform: none; }
  .read-progress::before { inset: 0 auto 0 0; width: calc(var(--progress) * 100%); height: auto; border-radius: 0; }
  .read-progress::after { display: none; }
  .research-title { font-size: 25px; letter-spacing: -.4px; }
  .research-article h2 { margin-top: 36px; font-size: 20px; }
  .stat { padding: 10px 12px; }
  .stat-value { font-size: 22px; }
}
@media (max-width: 380px) {
  .site-shell { padding-left: max(32px, env(safe-area-inset-left)); padding-right: max(32px, env(safe-area-inset-right)); }
  h1, .wordmark { font-size: 23px; letter-spacing: -.7px; }
  .header-links { gap: 12px; }
  .profile-link, .profile-link.resume-link { font-size: 12.5px; gap: 4px; }
  .about-intro { grid-template-columns: 98px minmax(0, 1fr); gap: 18px; }
  .portrait { width: 98px; height: 98px; }
  .hero-title { font-size: 26px; }
  .stat-grid { grid-template-columns: 1fr; }
  .research-title { font-size: 23px; }
  #preloader-text-title { font-size: 20px; letter-spacing: 1.2px; padding-left: 1.2px; }
}
/* Five header links still fit one row on 320px screens; targets stay 40x44. */
@media (max-width: 340px) {
  .header-links { gap: 6px; }
  .profile-link:not(.resume-link) { width: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
