/* Site layer — layout, responsiveness and page chrome.
   tokens.css (the Organic design system) is vendored verbatim and never edited
   here, so it can be re-synced from the design source at any time. Everything
   below takes its colours, fonts, radii and shadows from that file's variables. */

:root {
  --gutter: clamp(20px, 5vw, 48px);
  --measure: 1200px;
  --header-h: 66px;
}

body {
  background: var(--color-bg);
  font-family: var(--font-body);
  color: var(--color-text);
  font-size: 16px;
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

a { color: var(--color-accent-700); }
a:hover { color: var(--color-accent-800); }

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

img { max-width: 100%; height: auto; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 18px;
  background: var(--color-accent);
  color: var(--color-bg);
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ---------- Shared type ---------- */

.kicker {
  margin: 0 0 14px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-700);
}
.kicker--alt { color: var(--color-accent-2-700); }
.kicker--neutral { color: var(--color-neutral-700); }

.lede {
  margin: 0 0 28px;
  font-size: clamp(17px, 2vw, 19px);
  line-height: 1.6;
  color: var(--color-neutral-800);
  max-width: 50ch;
  text-wrap: pretty;
}

.muted { font-size: 14.5px; color: var(--color-neutral-700); }

.section-title {
  margin: 0 0 30px;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(30px, 4vw, 52px);
  line-height: 1.08;
  max-width: 20ch;
}

.panel-title {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.08;
}

.page-title {
  margin: 0 0 26px;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(36px, 5.4vw, 72px);
  line-height: 1.03;
  max-width: 17ch;
}

.btn-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.btn { text-decoration: none; }

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px var(--gutter);
  background: color-mix(in srgb, var(--color-bg) 84%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-divider);
}
.site-header--floating { position: fixed; left: 0; right: 0; }

.site-brand {
  font-family: var(--font-heading);
  font-size: 19px;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: 14.5px;
  font-weight: 600;
}
.site-nav a {
  text-decoration: none;
  color: var(--color-neutral-700);
}
.site-nav a:hover { color: var(--color-accent-700); }
.site-nav a[aria-current="page"] { color: var(--color-accent-700); }
.site-nav .btn { color: var(--color-text); }

.nav-burger { display: none; }

/* ---------- Home stage ---------- */

.stage { position: relative; height: 100vh; }
/* The tall scroll-driven stage only exists when the parallax script can run.
   Without JS it collapses to one screen so nobody scrolls past a frozen hero. */
.js .stage { height: 230vh; }

.stage-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.stage-ground { position: absolute; inset: 0; background: var(--color-neutral-100); }
.stage-cream { position: absolute; inset: 0; background: var(--color-bg); }

.graph-layer { position: absolute; inset: 0; opacity: 0.14; pointer-events: none; }

.graph-caption {
  position: absolute;
  left: var(--gutter);
  bottom: 46px;
  max-width: 34ch;
  opacity: 0;
  pointer-events: none;
}
.graph-caption p:last-child {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--color-neutral-700);
}
.graph-caption .kicker { margin-bottom: 6px; }

.hero {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: calc(var(--header-h) + 24px) var(--gutter) 60px;
}
/* Photo above the name, everything flush left. The whole hero has to fit inside
   one 100vh stage that clips its overflow, so the vertical rhythm is tied to vh
   as well as vw — on a short laptop window the photo and gaps shrink first. */
.hero-inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(16px, 2.4vh, 30px);
  width: 100%;
  max-width: var(--measure);
}
.hero-copy { min-width: 0; }
.hero-title {
  margin: 0 0 22px;
  font-family: var(--font-heading);
  font-weight: 400;
  /* Two lines of display type at 86px eat 172px of a stage that is only one
     viewport tall, so height is a constraint here as much as width. */
  font-size: clamp(40px, min(6.4vw, 9.5vh), 86px);
  line-height: 1;
  color: var(--color-text);
}

.hero-photo {
  width: clamp(124px, 16vh, 180px);
  aspect-ratio: 1;
  flex: none;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-surface);
  display: grid;
  place-items: center;
}
.hero-photo img { width: 100%; height: 100%; object-fit: cover; }

.scroll-cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
}
.scroll-cue-line { width: 1px; height: 34px; background: var(--color-neutral-400); }

.page-body {
  position: relative;
  z-index: 2;
  background: var(--color-bg);
  border-top: 1px solid var(--color-divider);
}

/* ---------- Sections ---------- */

.section {
  padding: clamp(56px, 8vw, 104px) var(--gutter) clamp(48px, 6vw, 72px);
  max-width: var(--measure);
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.section--tight { padding-top: 24px; padding-bottom: clamp(56px, 7vw, 88px); }
.section--flush { padding-top: 0; padding-bottom: clamp(64px, 8vw, 104px); }

.page-head { padding: clamp(48px, 7vw, 88px) var(--gutter) clamp(36px, 5vw, 56px); max-width: var(--measure); }
.page-head .lede { max-width: 62ch; }

.prose-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(24px, 3vw, 36px);
  max-width: 1000px;
}
.prose-grid p {
  margin: 0;
  font-size: 17px;
  line-height: 1.7;
  color: var(--color-neutral-800);
  text-wrap: pretty;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  max-width: 1100px;
}
.card-grid .card-kicker { font-size: 11px; letter-spacing: 0.12em; }
.card-grid .card-title { font-size: 20px; }
.card-grid .card-body { font-size: 15px; line-height: 1.6; opacity: 1; color: var(--color-neutral-800); }

.contact-panel {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: clamp(32px, 5vw, 52px) clamp(24px, 4vw, 48px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}
.contact-panel p {
  margin: 0;
  font-size: 17px;
  line-height: 1.6;
  color: var(--color-neutral-800);
  max-width: 46ch;
  text-wrap: pretty;
}
.contact-actions { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }

/* ---------- Panels used by inner pages ---------- */

.panel {
  background: var(--color-bg);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 4vw, 44px);
  box-shadow: var(--shadow-sm);
}
.panel--surface { background: var(--color-surface); box-shadow: none; }
.panel h2 {
  margin: 16px 0 12px;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(24px, 3vw, 30px);
  line-height: 1.12;
}
.panel p {
  margin: 0 0 14px;
  font-size: 16.5px;
  line-height: 1.7;
  color: var(--color-neutral-800);
  text-wrap: pretty;
  max-width: 70ch;
}
.panel p:last-child { margin-bottom: 0; }

.panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
}

.tag-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 18px; }

/* Inner pages sit on the darker ground so the white panels read as raised. */
body.inner { background: var(--color-neutral-100); }
body.inner .site-header { background: color-mix(in srgb, var(--color-neutral-100) 84%, transparent); }

/* ---------- Definition list (CV / summary rows) ---------- */

.def-list {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 18px 32px;
  max-width: 820px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--color-neutral-800);
}
.def-list dt { font-weight: 700; color: var(--color-text); margin: 0; }
.def-list dd { margin: 0; }

/* ---------- Tables ---------- */

.table-wrap { overflow-x: auto; max-width: 1000px; }
.table-wrap .table { font-size: 15px; min-width: 560px; }
.table-wrap .table td { vertical-align: top; }

/* ---------- Notes ---------- */

.note-body {
  max-width: 68ch;
  font-size: 17.5px;
  line-height: 1.75;
  color: var(--color-neutral-900);
}
.note-body p { margin: 0 0 1.15em; text-wrap: pretty; }
.note-body h2 {
  margin: 2em 0 0.6em;
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(24px, 3vw, 32px);
  line-height: 1.15;
}
.note-body h3 { margin: 1.6em 0 0.5em; font-size: 21px; }
.note-body ul, .note-body ol { margin: 0 0 1.15em; padding-left: 1.3em; }
.note-body li { margin-bottom: 0.4em; }
.note-body blockquote {
  margin: 1.5em 0;
  padding: 4px 0 4px 20px;
  border-left: 3px solid var(--color-accent-300);
  color: var(--color-neutral-700);
}
.note-body code {
  font-size: 0.9em;
  padding: 2px 5px;
  border-radius: 5px;
  background: var(--color-neutral-200);
}
.note-body pre {
  overflow-x: auto;
  padding: 18px 20px;
  border-radius: var(--radius-md);
  background: var(--color-neutral-200);
}
.note-body pre code { padding: 0; background: none; }

/* Display maths can be wider than the measure — let it scroll on its own
   rather than pushing the page sideways. */
.note-body .katex-display {
  overflow-x: auto;
  overflow-y: hidden;
  padding: 4px 0 10px;
}

.note-card { text-decoration: none; color: inherit; transition: box-shadow 0.18s ease, transform 0.18s ease; }
.note-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.note-card .card-title { color: var(--color-text); }

.talk-items { margin: 0 0 14px; padding-left: 1.2em; color: var(--color-neutral-800); font-size: 16px; line-height: 1.65; }
.talk-items li { margin-bottom: 6px; }

.panel ul { margin: 0; padding-left: 1.2em; color: var(--color-neutral-800); font-size: 16px; line-height: 1.7; }
.panel ul li { margin-bottom: 8px; }

/* ---------- Footer ---------- */

.site-footer {
  padding: 26px var(--gutter) 40px;
  border-top: 1px solid var(--color-divider);
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  font-size: 13.5px;
  color: var(--color-neutral-600);
}
.footer-links { display: flex; flex-wrap: wrap; gap: 22px; }
.site-footer a { text-decoration: none; }

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  .nav-burger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    padding: 8px;
    cursor: pointer;
    border-radius: var(--radius-sm);
  }
  .nav-burger span {
    display: block;
    height: 2px;
    background: var(--color-text);
    border-radius: 2px;
  }
  .nav-toggle:focus-visible + .nav-burger { outline: 2px solid var(--color-accent); outline-offset: 2px; }

  .site-header { flex-wrap: wrap; }
  /* The home page's fixed header would sit on top of the hero once the stage
     is back in normal flow, so it becomes sticky like every other page. */
  .site-header--floating { position: sticky; }

  .site-nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 12px 0 6px;
    font-size: 16px;
  }
  .nav-toggle:checked ~ .site-nav { display: flex; }
  .site-nav a { padding: 10px 2px; }
  .site-nav .btn { margin-top: 6px; }

  /* The scroll-driven stage is desktop-only; hero-scroll.js bails out below
     900px, so the hero becomes an ordinary block here. */
  .stage, .js .stage { height: auto; }
  .stage-sticky { position: static; height: auto; overflow: visible; }
  /* The ground and cream layers only exist to cross-fade behind the parallax.
     With .hero back in normal flow they would paint over it, so they go. */
  .stage-ground, .stage-cream, .graph-layer, .scroll-cue, .graph-caption { display: none; }
  .hero {
    position: relative;
    z-index: 1;
    padding: 40px var(--gutter) 56px;
  }
  /* The stage is in normal flow here, so height is no longer a constraint and
     the photo can go back to sizing off the viewport width. */
  .hero-inner { gap: 28px; }
  .hero-photo { width: clamp(132px, 34vw, 190px); }
  .hero-title { font-size: clamp(44px, 11vw, 64px); }
  .page-body { border-top: 0; }

  .def-list { grid-template-columns: 1fr; gap: 4px 0; }
  .def-list dd { margin-bottom: 14px; }
}

@media (max-width: 600px) {
  .contact-panel { flex-direction: column; align-items: flex-start; }
  .contact-actions { width: 100%; }
  .contact-actions .btn { width: 100%; justify-content: center; word-break: break-all; }
  .site-footer { flex-direction: column; gap: 12px; }
  .footer-links { gap: 14px; }
}

/* ---------- Print ---------- */

@media print {
  .site-header, .site-footer, .skip-link, .graph-layer, .scroll-cue, .btn-row, .no-print { display: none !important; }
  body, body.inner { background: #fff; color: #000; }
  .panel { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
  a { color: #000; text-decoration: underline; }
  .def-list { grid-template-columns: 150px 1fr; }
}

/* Small tag sitting inline in a definition-list row (e.g. an upcoming
   workshop), nudged to align with the text baseline beside it. */
.tag-inline {
  margin-left: 8px;
  vertical-align: 2px;
  font-size: 11px;
}
