@import url("variables.css?v=2");

/* ==========================================================================
   Reset
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
img, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }

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

body {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--color-text);
  background-color: var(--color-bg);
  /* One continuous, static warm wash (the same tint as the home hero
     glow) — a single diagonal linear-gradient interpolating directly
     between the two warm tones with no transparent stop anywhere, so
     there's no seam or "dead zone" the way two separate radial glows
     fading to transparent would leave (that was the previous approach;
     it left a visible hard edge where each one's falloff ended). This
     MUST use `background-attachment: fixed` with an explicit
     `background-size: 100vw 100vh` — with the default `scroll`
     attachment, the gradient's box is the *entire scrollable element*,
     so on a long page (several thousand px tall) the browser ends up
     computing the gradient across a many-thousand-px span, which is
     pathologically expensive and can fail to paint at all. `fixed`
     bounds it to the viewport instead — cheap, no blur/filter to
     resample (unlike the header below), and it keeps the same
     continuous wash present at every scroll position since it's
     viewport-anchored, not page-anchored. Cards and text sit on their
     own opaque/solid backgrounds, so this never affects legibility.
     Faceted isometric mesh on top of that nods to a triangulated
     STL / 3D-print model surface, layered at two scales for depth.
     Pure CSS throughout, no images. */
  background-image:
    linear-gradient(to bottom left, var(--hero-glow) 0%, var(--hero-glow-ember) 100%),
    repeating-linear-gradient(60deg, var(--mesh-major) 0, var(--mesh-major) 1px, transparent 1px, transparent 192px),
    repeating-linear-gradient(-60deg, var(--mesh-major) 0, var(--mesh-major) 1px, transparent 1px, transparent 192px),
    repeating-linear-gradient(0deg, var(--mesh-major) 0, var(--mesh-major) 1px, transparent 1px, transparent 192px),
    repeating-linear-gradient(60deg, var(--mesh-minor) 0, var(--mesh-minor) 1px, transparent 1px, transparent 48px),
    repeating-linear-gradient(-60deg, var(--mesh-minor) 0, var(--mesh-minor) 1px, transparent 1px, transparent 48px),
    repeating-linear-gradient(0deg, var(--mesh-minor) 0, var(--mesh-minor) 1px, transparent 1px, transparent 48px);
  background-size: 100vw 100vh, auto, auto, auto, auto, auto, auto;
  background-attachment: fixed, scroll, scroll, scroll, scroll, scroll, scroll;
  transition: background-color var(--transition-base), color var(--transition-base);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main { flex: 1; }

.container {
  width: 100%;
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--space-5);
}
.container--wide { max-width: var(--content-width-wide); }

/* ==========================================================================
   Typography
   ========================================================================== */
h1, h2, h3, h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  color: var(--color-text);
}
h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

p { color: var(--color-text-secondary); }

.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-3);
}

.section-heading {
  margin-bottom: var(--space-6);
}
.section-heading p {
  margin-top: var(--space-2);
  font-size: var(--fs-md);
}

.text-muted { color: var(--color-text-muted); }

.link-accent {
  color: var(--color-accent);
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition-fast);
}
.link-accent:hover { border-color: currentColor; }

/* ==========================================================================
   Skip link (accessibility)
   ========================================================================== */
.skip-link {
  position: absolute;
  top: -100px;
  left: var(--space-4);
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  z-index: 200;
  transition: top var(--transition-fast);
}
.skip-link:focus { top: var(--space-4); }

/* ==========================================================================
   Header / Nav
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--color-bg) 94%, transparent);
  border-bottom: var(--border-width) solid var(--color-border);
  transform: translateZ(0);
}
/* backdrop-filter forces a re-composite of everything beneath a sticky
   header on every scroll frame, which is costly on mobile GPUs. Only
   enable the frosted-glass look on pointer:fine (desktop/trackpad)
   devices where scrolling doesn't touch it the same way; skip it on
   touch devices. */
@media (min-width: 721px) and (pointer: fine) {
  .site-header {
    background: color-mix(in srgb, var(--color-bg) 88%, transparent);
    backdrop-filter: blur(8px);
  }
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-4);
  max-width: var(--content-width-wide);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.nav-brand {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: var(--fs-md);
  white-space: nowrap;
}
.nav-brand span { color: var(--color-accent); }

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.nav-links a {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-text-secondary);
  padding-block: var(--space-1);
  border-bottom: 2px solid transparent;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}
.nav-links a:hover { color: var(--color-text); }
.nav-links a[aria-current="page"] {
  color: var(--color-text);
  border-color: var(--color-accent);
}

.nav-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.theme-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}
.theme-toggle:hover { background: var(--color-surface-hover); transform: translateY(-1px); }
.theme-toggle:active { transform: translateY(0); }
.theme-toggle svg {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  stroke: var(--color-text);
  transform: translate(-50%, -50%) rotate(0deg) scale(1);
  opacity: 1;
  transition: opacity var(--transition-base), transform var(--transition-base);
}
.theme-toggle .icon-sun { opacity: 0; transform: translate(-50%, -50%) rotate(-90deg) scale(0.4); }
:root[data-theme="dark"] .theme-toggle .icon-sun { opacity: 1; transform: translate(-50%, -50%) rotate(0deg) scale(1); }
:root[data-theme="dark"] .theme-toggle .icon-moon { opacity: 0; transform: translate(-50%, -50%) rotate(90deg) scale(0.4); }

.nav-toggle {
  display: none;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.nav-toggle svg { width: 20px; height: 20px; stroke: var(--color-text); }

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  border: var(--border-width) solid transparent;
  cursor: pointer;
  transition: transform var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--color-accent);
  color: var(--color-accent-contrast);
}
.btn--primary:hover { background: var(--color-accent-hover); box-shadow: var(--shadow-md); }

.btn--outline {
  background: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text);
}
.btn--outline:hover { background: var(--color-surface-hover); box-shadow: var(--shadow-sm); }

.btn--sm { padding: var(--space-2) var(--space-4); font-size: var(--fs-xs); }

/* ==========================================================================
   Hero (Home)
   ========================================================================== */
.hero {
  padding-block: var(--space-9) var(--space-8);
}
.hero-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-8);
  align-items: center;
}
.hero-text h1 { margin-bottom: var(--space-4); }
.hero-text .lede {
  font-size: var(--fs-md);
  max-width: 60ch;
  margin-bottom: var(--space-6);
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Hero entrance: always above the fold on load, so this runs as a plain
   CSS keyframe (deterministic, no scroll/observer dependency at all)
   rather than the below-the-fold scroll-reveal system. */
@keyframes hero-in {
  from { opacity: 0; transform: translateY(var(--reveal-distance)); }
  to { opacity: 1; transform: translateY(0); }
}
.hero-text > *, .avatar {
  opacity: 0;
  animation: hero-in var(--reveal-duration) var(--ease-out) both;
}
.hero-text > *:nth-child(1) { animation-delay: 0ms; }
.hero-text > *:nth-child(2) { animation-delay: 90ms; }
.hero-text > *:nth-child(3) { animation-delay: 180ms; }
.hero-text > *:nth-child(4) { animation-delay: 270ms; }
.hero-text > *:nth-child(5) { animation-delay: 360ms; }
.avatar { animation-delay: 150ms; }
@media (prefers-reduced-motion: reduce) {
  .hero-text > *, .avatar { animation: none; opacity: 1; }
}

.avatar {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: var(--color-accent-soft);
  border: var(--border-width) solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--transition-base); }
.avatar:hover img { transform: scale(1.06); }
.avatar svg { width: 55%; height: 55%; stroke: var(--color-accent); opacity: 0.6; }

/* Social row */
.social-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
.social-links a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  padding: var(--space-2) var(--space-4);
  border-radius: 999px;
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  transition: border-color var(--transition-fast), background var(--transition-fast), transform var(--transition-fast);
}
.social-links a:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
  transform: translateY(-1px);
}
.social-links svg { width: 16px; height: 16px; stroke: currentColor; }

/* Research interests tags */
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.tag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  background: var(--color-tag-bg);
  color: var(--color-tag-text);
}

/* ==========================================================================
   Generic sections
   ========================================================================== */
.section {
  padding-block: var(--space-8);
  border-top: var(--border-width) solid var(--color-border);
}
.section:first-child { border-top: none; }

.card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
/* !important on transform: once the scroll-driven reveal animation (see
   .reveal-scroll) finishes, it holds `transform` via fill-mode. A plain
   hover rule on the same element can't outrank a running/filled CSS
   animation in the cascade, so this needs the boost to still lift on hover. */
.card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px) !important; border-color: var(--color-border-strong); }

/* ==========================================================================
   Scroll-reveal (js/reveal.js)
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition: opacity var(--reveal-duration) var(--ease-out), transform var(--reveal-duration) var(--ease-out);
  will-change: opacity, transform;
}
.reveal.is-visible { opacity: 1; transform: translateY(0); will-change: auto; }

/* Scroll-linked reveal (preferred, used when the browser supports it;
   see js/reveal.js). The element's opacity/position are driven directly
   by its own scroll position every frame, on the compositor, with no JS
   in the loop at all, so it can never drift or lag behind the scroll
   the way a JS-timed transition can. `linear` is intentional: the
   timeline itself already *is* the scroll progress, so easing here would
   just make the motion feel disconnected from the finger/wheel again. */
@keyframes reveal-in {
  from { opacity: 0; transform: translateY(var(--reveal-distance)); }
  to { opacity: 1; transform: translateY(0); }
}
.reveal-scroll {
  animation: reveal-in linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 55%;
  will-change: opacity, transform;
}

@media (prefers-reduced-motion: reduce) {
  .reveal { transition: none; opacity: 1; transform: none; will-change: auto; }
  .reveal-scroll { animation: none; opacity: 1; transform: none; will-change: auto; }
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

/* ==========================================================================
   Publications / Research page
   ========================================================================== */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.filter-btn {
  font-size: var(--fs-sm);
  font-weight: 500;
  padding: var(--space-2) var(--space-4);
  border-radius: 999px;
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.filter-btn:hover { border-color: var(--color-accent); color: var(--color-text); }
.filter-btn[aria-pressed="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-contrast);
}
.filter-count {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  font-family: var(--font-mono);
}

.pub-search {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  margin-bottom: var(--space-6);
}
.pub-search:focus {
  outline: none;
  border-color: var(--color-accent);
}

.pub-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.pub-item {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.pub-item:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-sm); transform: translateY(-2px) !important; }

.pub-type {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px var(--space-2);
  border-radius: 4px;
  margin-bottom: var(--space-3);
  color: var(--color-accent);
  background: var(--color-accent-soft);
}

.pub-title {
  font-family: var(--font-serif);
  font-size: var(--fs-md);
  font-weight: 600;
  margin-bottom: var(--space-2);
  line-height: var(--lh-tight);
}
.pub-authors {
  font-size: var(--fs-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-1);
}
.pub-authors .me { font-weight: 700; color: var(--color-text); }
.pub-venue {
  font-size: var(--fs-sm);
  font-style: italic;
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}

.pub-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.pub-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--color-text-secondary);
  border: var(--border-width) solid var(--color-border);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  background: transparent;
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
.pub-action:hover { border-color: var(--color-accent); color: var(--color-accent); }
.pub-action svg { width: 13px; height: 13px; stroke: currentColor; }

.bibtex-block {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  margin-top: 0;
  padding-inline: var(--space-4);
  padding-block: 0;
  background: var(--color-bg-alt);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: var(--lh-loose);
  color: var(--color-text-secondary);
  white-space: pre-wrap;
  word-break: break-word;
  position: relative;
  transition: max-height var(--transition-base), opacity var(--transition-base), margin-top var(--transition-base), padding-block var(--transition-base), border-color var(--transition-base);
}
.bibtex-block.is-open {
  max-height: 640px;
  opacity: 1;
  margin-top: var(--space-4);
  padding-block: var(--space-4);
  border-color: var(--color-border);
}
.bibtex-copy {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
}

.empty-state {
  text-align: center;
  padding: var(--space-8) var(--space-4);
  color: var(--color-text-muted);
}

/* ==========================================================================
   Research projects page
   ========================================================================== */
.project-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.project-card {
  display: grid;
  grid-template-columns: minmax(0, 320px) 1fr;
  gap: var(--space-6);
  align-items: start;
}

.project-image {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-accent-soft);
  border: var(--border-width) solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.project-image img { width: 100%; height: 100%; object-fit: cover; }
.project-image:has(.project-zoom) { aspect-ratio: auto; display: block; }
.project-zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.project-zoom img { height: auto; display: block; }
.project-zoom:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* Click-to-enlarge popup */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6) var(--space-4);
  background: rgba(10, 12, 16, 0.86);
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
  cursor: zoom-out;
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; }
.lightbox-img {
  max-width: min(94vw, 1100px);
  max-height: 88vh;
  width: auto;
  height: auto;
  border-radius: var(--radius-sm);
  background: #fff;
  box-shadow: var(--shadow-lg);
  cursor: default;
  transform: scale(0.97);
  transition: transform 200ms var(--ease-out);
}
.lightbox.is-open .lightbox-img { transform: scale(1); }
.lightbox-close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  cursor: pointer;
  transition: background var(--transition-fast);
}
.lightbox-close:hover,
.lightbox-close:focus-visible { background: rgba(255, 255, 255, 0.28); }
.lightbox-close svg { width: 22px; height: 22px; stroke: #fff; }
html.lightbox-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) {
  .lightbox, .lightbox-img { transition: none; }
}
.project-placeholder-icon svg {
  width: 40%;
  height: 40%;
  stroke: var(--color-accent);
  opacity: 0.5;
}

.project-body { padding-top: var(--space-1); }
.project-tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--color-accent);
  margin-bottom: var(--space-2);
}
.project-body h3 { margin-bottom: var(--space-3); }
.project-body p {
  font-size: var(--fs-sm);
  line-height: var(--lh-loose);
  margin-bottom: var(--space-4);
}
.project-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-accent);
}
.project-link svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  transition: transform var(--transition-fast);
}
.project-link:hover svg { transform: translateX(3px); }

/* ==========================================================================
   Contact page
   ========================================================================== */
.contact-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}
.contact-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-3);
}
.contact-icon svg { width: 20px; height: 20px; stroke: var(--color-accent); }
.contact-card h3 { font-size: var(--fs-sm); color: var(--color-text-muted); font-weight: 500; margin-bottom: var(--space-1); }
.contact-card .contact-value {
  font-size: var(--fs-md);
  font-family: var(--font-serif);
  color: var(--color-text);
  line-height: var(--lh-normal);
}
a.contact-value:hover { color: var(--color-accent); }

.card-grid--3 { grid-template-columns: repeat(3, 1fr); }

/* ==========================================================================
   Privacy policy / legal prose
   ========================================================================== */
.policy-content { max-width: 680px; }
.policy-content h2 {
  font-size: var(--fs-lg);
  margin-top: var(--space-7);
  margin-bottom: var(--space-3);
}
.policy-content h2:first-child { margin-top: 0; }
.policy-content p { margin-bottom: var(--space-4); }
.policy-content ul {
  list-style: disc;
  padding-left: 1.25em;
  margin-bottom: var(--space-4);
}
.policy-content li { color: var(--color-text-secondary); margin-bottom: var(--space-2); }
.policy-content code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--color-tag-bg);
  color: var(--color-tag-text);
  padding: 1px 5px;
  border-radius: 4px;
}

/* ==========================================================================
   Teaching page
   ========================================================================== */
.teach-item {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: var(--space-5);
  padding-block: var(--space-5);
  padding-inline: var(--space-4);
  margin-inline: calc(-1 * var(--space-4));
  border-top: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast);
}
.teach-item:hover { background-color: var(--color-surface-hover); }
.teach-item:first-of-type { border-top: none; padding-top: 0; }
.teach-term {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  padding-top: var(--space-1);
}
.teach-role {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--color-accent);
  margin-bottom: var(--space-1);
}
.teach-title { margin-bottom: var(--space-2); }
.teach-desc { font-size: var(--fs-sm); margin-bottom: var(--space-3); }
.teach-links { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.teach-links a { font-size: var(--fs-xs); font-weight: 600; color: var(--color-accent); }
.teach-links a:hover { text-decoration: underline; }

/* ==========================================================================
   People page
   ========================================================================== */
.people-group { margin-bottom: var(--space-8); }
.people-group:last-child { margin-bottom: 0; }

.people-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-5);
}

.person-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-1);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-4);
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.person-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px) !important; border-color: var(--color-border-strong); }

.person-photo {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-3);
}
.person-photo img { transition: transform var(--transition-base); }
.person-card:hover .person-photo img { transform: scale(1.06); }
.person-photo img { width: 100%; height: 100%; object-fit: cover; }
.person-initials {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: var(--fs-2xl);
  color: var(--color-accent);
}

.person-info { min-width: 0; }
.person-name {
  display: block;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 2px;
}
a.person-name:hover { color: var(--color-accent); }
.person-title { font-size: var(--fs-sm); color: var(--color-text-secondary); }
.person-org { font-size: var(--fs-xs); color: var(--color-text-muted); }

.person-lab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 4px var(--space-3) 4px 4px;
  border-radius: 999px;
  border: var(--border-width) solid var(--color-border);
  background: var(--color-bg-alt);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--color-text-secondary);
  transition: border-color var(--transition-fast), color var(--transition-fast);
}
.person-lab:hover { border-color: var(--color-accent); color: var(--color-accent); }
.person-lab img {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

/* ==========================================================================
   CV / Timeline
   ========================================================================== */
.cv-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-8);
}

.timeline {
  position: relative;
  padding-left: var(--space-6);
  border-left: 2px solid var(--color-border);
}
.timeline-item {
  position: relative;
  padding-bottom: var(--space-6);
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-item::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-6) - 6px);
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-accent);
  transition: transform var(--transition-fast);
  border: 3px solid var(--color-bg);
  box-shadow: 0 0 0 2px var(--color-border);
}
.timeline-item:hover::before { transform: scale(1.25); }
.timeline-year {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}
.timeline-title { margin-bottom: var(--space-1); }
.timeline-org { font-size: var(--fs-sm); color: var(--color-text-secondary); margin-bottom: var(--space-1); }
.timeline-detail { font-size: var(--fs-sm); color: var(--color-text-muted); }

.skill-group { margin-bottom: var(--space-5); }
.skill-group:last-child { margin-bottom: 0; }
.skill-group h4 { margin-bottom: var(--space-3); }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  border-top: var(--border-width) solid var(--color-border);
  padding-block: var(--space-6);
  margin-top: var(--space-8);
}
.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}
.footer-inner .social-links { margin-top: 0; }
.footer-inner a:hover { color: var(--color-accent); }

.footer-legal {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: var(--border-width) solid var(--color-border);
  font-size: 0.7rem;
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
}
.footer-legal a { color: var(--color-text-muted); text-decoration: underline; }
.footer-legal a:hover { color: var(--color-accent); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 860px) {
  .card-grid { grid-template-columns: 1fr; }
  .cv-two-col { grid-template-columns: 1fr !important; }
}

@media (max-width: 720px) {
  h1 { font-size: var(--fs-2xl); }
  h2 { font-size: var(--fs-xl); }

  .nav-toggle { display: inline-flex; }
  .nav-links {
    position: fixed;
    inset: 64px var(--space-4) auto var(--space-4);
    flex-direction: column;
    align-items: stretch;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    box-shadow: var(--shadow-lg);
    gap: var(--space-1);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-8px);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
  }
  .nav-links.is-open {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }
  .nav-links a {
    padding: var(--space-3);
    border-bottom: none;
    border-radius: var(--radius-sm);
  }
  .nav-links a[aria-current="page"] { background: var(--color-accent-soft); }

  .hero-grid {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .hero-text .lede { margin-inline: auto; }
  .hero-actions { justify-content: center; }
  .social-links { justify-content: center; }
  .avatar { margin-inline: auto; width: 160px; height: 160px; order: -1; margin-bottom: var(--space-5); }

  .teach-item { grid-template-columns: 1fr; gap: var(--space-2); }

  .project-card { grid-template-columns: 1fr; }
  .project-image { aspect-ratio: 16 / 9; }

  .filter-count { width: 100%; margin-left: 0; order: -1; }

  .footer-inner { flex-direction: column; text-align: center; }
  .footer-legal { text-align: center; }
}
