:root {
  --navy: #0c234e;
  --navy-soft: #1c2a44;
  --teal: #0a5d50;        /* dark jade */
  --ink: #243043;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;            /* scrolling disabled */
  background: #ffffff;
  overscroll-behavior: none;
}

body {
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  font-optical-sizing: auto;
  touch-action: pan-y;
}

/* ---------- animated gradient field ---------- */
.stage {
  position: fixed; inset: -40%; z-index: 0; pointer-events: none;
  transition: transform 1s cubic-bezier(0.5, 0.05, 0.2, 1);
  will-change: transform;
}
.blob { position: absolute; border-radius: 50%; filter: blur(75px); will-change: transform; }
/* jade */
.b1 {
  width: 74vmax; height: 74vmax; left: -18vmax; top: -22vmax;
  background: radial-gradient(circle at 30% 30%, rgba(10,93,80,0.78), rgba(10,93,80,0) 72%);
  animation: drift1 13s ease-in-out infinite;
}
/* teal */
.b2 {
  width: 66vmax; height: 66vmax; right: -18vmax; top: 0vmax;
  background: radial-gradient(circle at 40% 40%, rgba(20,150,150,0.6), rgba(20,150,150,0) 72%);
  animation: drift2 16s ease-in-out infinite;
}
/* blue */
.b3 {
  width: 70vmax; height: 70vmax; left: 4vmax; bottom: -28vmax;
  background: radial-gradient(circle at 50% 50%, rgba(26,71,130,0.72), rgba(26,71,130,0) 72%);
  animation: drift3 18s ease-in-out infinite;
}
/* silver */
.b4 {
  width: 62vmax; height: 62vmax; right: 2vmax; bottom: -16vmax;
  background: radial-gradient(circle at 50% 50%, rgba(190,198,212,0.75), rgba(190,198,212,0) 72%);
  animation: drift4 15s ease-in-out infinite;
}
/* second layer — mirrored / offset arrangement and out-of-phase drift, so the
   clouds that sweep in read as a different formation rather than a repeat. */
.stage-alt .b1 { left: auto; right: -20vmax; top: -16vmax;    animation-delay: -7s; }
.stage-alt .b2 { right: auto; left: -16vmax; top: 6vmax;      animation-delay: -4s; }
.stage-alt .b3 { left: auto; right: 0vmax;   bottom: -24vmax; animation-delay: -11s; }
.stage-alt .b4 { right: auto; left: -2vmax;  bottom: -12vmax; animation-delay: -6s; }
.veil {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(ellipse 75% 65% at 50% 40%,
    rgba(255,255,255,0.92) 0%, rgba(255,255,255,0.68) 38%, rgba(255,255,255,0) 78%);
}

@keyframes drift1 {
  0%   { transform: translate(0,0) scale(1) rotate(0deg); }
  33%  { transform: translate(16vmax,10vmax) scale(1.18) rotate(8deg); }
  66%  { transform: translate(6vmax,18vmax) scale(0.92) rotate(-6deg); }
  100% { transform: translate(0,0) scale(1) rotate(0deg); }
}
@keyframes drift2 {
  0%   { transform: translate(0,0) scale(1.05); }
  40%  { transform: translate(-18vmax,8vmax) scale(0.9); }
  70%  { transform: translate(-8vmax,-12vmax) scale(1.2); }
  100% { transform: translate(0,0) scale(1.05); }
}
@keyframes drift3 {
  0%   { transform: translate(0,0) scale(1); }
  35%  { transform: translate(14vmax,-14vmax) scale(1.15); }
  70%  { transform: translate(-10vmax,-6vmax) scale(0.9); }
  100% { transform: translate(0,0) scale(1); }
}
@keyframes drift4 {
  0%   { transform: translate(0,0) scale(1); }
  30%  { transform: translate(-12vmax,-10vmax) scale(1.12); }
  65%  { transform: translate(10vmax,8vmax) scale(0.92); }
  100% { transform: translate(0,0) scale(1); }
}

/* ---------- shell ---------- */
.page {
  position: relative; z-index: 2;
  height: 100vh;
  height: 100dvh;            /* dynamic viewport — accounts for mobile browser chrome */
  width: 100%;
  display: flex; flex-direction: column;
}

/* masthead — name at the top */
.masthead {
  flex: none;
  text-align: center;
  padding: 4.5vh 24px 1.6rem;
  border-bottom: 2px solid rgba(255,255,255,0.9);
  box-shadow: 0 1px 0 rgba(12,35,78,0.06);
}
.kicker {
  font-size: 0.92rem; font-weight: 600; letter-spacing: 3.5px;
  text-transform: uppercase; color: var(--teal); margin: 0 0 0.9rem;
}
.name {
  font-family: "Fraunces", Georgia, serif; font-weight: 600;
  /* width-driven, but also capped by height so it shrinks on short screens */
  font-size: min(clamp(2.6rem, 6.5vw, 4.4rem), 9.5vh); line-height: 1;
  letter-spacing: -0.5px; color: var(--navy); margin: 0;
  cursor: pointer;
}
.credential {
  font-size: 0.84rem; font-weight: 500; letter-spacing: 2.5px;
  text-transform: uppercase; color: var(--navy-soft); margin: 0.9rem 0 0.4rem;
}
.affiliation {
  font-family: "Fraunces", Georgia, serif;
  font-style: italic; font-weight: 500;
  font-size: 1.3rem; line-height: 1.45; letter-spacing: 0.2px;
  color: var(--navy-soft); margin: 0;
}

/* ---------- carousel (3D ring) ---------- */
.carousel {
  flex: 1; position: relative; overflow: hidden;
}
.track {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  /* hidden until JS positions the slides — prevents the initial stacked flash */
  opacity: 0;
  transition: opacity 0.6s ease;
}
.track.is-ready { opacity: 1; }
.slide {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: safe center;   /* centre when it fits, scroll from top when it doesn't */
  text-align: center;
  padding: 2vh 9vw 14vh;   /* extra bottom padding lifts the centred content up */
  overflow-y: auto;        /* the slide scrolls when its content is taller than the carousel */
  scrollbar-width: thin; scrollbar-color: rgba(12,35,78,0.18) transparent;
  /* soften the scroll edges so overflowing content fades rather than cuts */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  backface-visibility: hidden;
  will-change: transform, opacity;
  transition: transform 0.85s cubic-bezier(0.55, 0.05, 0.25, 1),
              opacity 0.85s ease;
}
.slide::-webkit-scrollbar { width: 6px; }
.slide::-webkit-scrollbar-thumb { background: rgba(12,35,78,0.18); border-radius: 3px; }

.slide h2 {
  display: inline-flex; align-items: center; gap: 14px;
  font-size: 1.15rem; font-weight: 600; letter-spacing: 4px;
  text-transform: uppercase; color: var(--teal); margin: 0 0 2.1rem;
}
/* TP monogram (transparent SVG) + hairline rule flanking each heading:  TP —  HEADING  — TP */
.slide h2::before, .slide h2::after {
  content: ""; flex: none; width: 3.4em; height: 1.7em;
  background-repeat: no-repeat;
}
.slide h2::before {
  background-image:
    url("resources/tp_bulletpoint.svg"),
    linear-gradient(rgba(10, 93, 80, 0.5), rgba(10, 93, 80, 0.5));
  background-position: left center, right center;
  background-size: 1.7em 1.7em, 1.4em 1.4px;
}
.slide h2::after {
  background-image:
    url("resources/tp_bulletpoint.svg"),
    linear-gradient(rgba(10, 93, 80, 0.5), rgba(10, 93, 80, 0.5));
  background-position: right center, left center;
  background-size: 1.7em 1.7em, 1.4em 1.4px;
}

.slide p.body {
  font-size: clamp(1rem, 1.4vw, 1.18rem); line-height: 1.95; font-weight: 300;
  color: var(--ink); margin: 0; max-width: 640px; text-align: center;
}
.slide .placeholder {
  font-family: "Fraunces", Georgia, serif; font-style: italic; font-weight: 500;
  font-size: clamp(1.2rem, 2.4vw, 1.55rem); color: var(--navy-soft);
  max-width: 30ch; margin: 0; line-height: 1.55;
}

/* ---------- publications ---------- */
.pubs {
  list-style: none; margin: 0; padding: 0.25rem 0.5rem;
  width: 100%; max-width: 760px; text-align: left;
  counter-reset: pub;       /* natural height — the slide scrolls if it overflows */
}

.pub { position: relative; padding-left: 2.4rem; }
.pub + .pub { margin-top: 1.6rem; padding-top: 1.6rem; border-top: 1px solid rgba(12,35,78,0.1); }
.pub::before {
  counter-increment: pub; content: counter(pub, decimal-leading-zero);
  position: absolute; left: 0; top: 0.15rem;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.5px;
  color: var(--teal); opacity: 0.85;
}
.pub + .pub::before { top: 1.75rem; }

.pub-title {
  font-family: "Fraunces", Georgia, serif; font-weight: 600;
  font-size: clamp(1.1rem, 1.65vw, 1.42rem); line-height: 1.3;
  letter-spacing: -0.2px; color: var(--navy); margin: 0 0 0.55rem;
}
.pub-authors {
  font-size: 0.85rem; line-height: 1.6; font-weight: 400;
  color: rgba(36,48,67,0.7); margin: 0 0 0.5rem;
}
.pub-authors .me { font-weight: 700; color: var(--teal); }
.pub-year {
  display: inline-block; margin-left: 0.5rem; padding-left: 0.5rem;
  border-left: 1px solid rgba(12,35,78,0.22);
  font-weight: 600; color: var(--navy-soft);
}
.pub-venue {
  font-family: "Fraunces", Georgia, serif; font-style: italic; font-weight: 500;
  font-size: 1rem; line-height: 1.45; color: var(--navy-soft); margin: 0 0 0.6rem;
}
.pub-venue .vol { font-style: normal; font-family: "Hanken Grotesk", sans-serif; font-size: 0.9rem; color: rgba(36,48,67,0.7); }
.pub-link {
  display: inline-block; font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.3px; text-decoration: none; color: var(--teal);
  border-bottom: 1px solid rgba(10,93,80,0.3); padding-bottom: 1px;
  transition: color 0.2s ease, border-color 0.2s ease;
  word-break: break-word;
}
.pub-link:hover { color: var(--navy); border-color: var(--navy); }

/* ---------- resume / education ---------- */
.resume {
  width: 100%; max-width: 720px; text-align: left; padding: 0.25rem 0.5rem;
  /* natural height — the slide scrolls if it overflows */
}
.resume-label {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 2.5px;
  text-transform: uppercase; color: var(--teal); margin: 0 0 1.4rem;
  padding-bottom: 0.7rem; border-bottom: 1px solid rgba(10,93,80,0.22);
}
.edu { list-style: none; margin: 0; padding: 0; }
.edu-item {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: 0 1.8rem;
}
.edu-item + .edu-item {
  margin-top: 1.7rem; padding-top: 1.7rem; border-top: 1px solid rgba(12,35,78,0.1);
}
.edu-dates {
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.6px;
  color: var(--teal); padding-top: 0.35rem; white-space: nowrap;
}
.edu-degree {
  font-family: "Fraunces", Georgia, serif; font-weight: 600;
  font-size: clamp(1.1rem, 1.6vw, 1.4rem); line-height: 1.3;
  letter-spacing: -0.2px; color: var(--navy); margin: 0 0 0.45rem;
}
.edu-school {
  font-size: 0.95rem; font-weight: 600; color: var(--navy-soft);
  margin: 0 0 0.3rem; line-height: 1.4;
}
.edu-loc {
  display: block; font-size: 0.85rem; font-weight: 400;
  color: rgba(36,48,67,0.6); margin-top: 0.1rem;
}
.edu-dept {
  font-family: "Fraunces", Georgia, serif; font-style: italic; font-weight: 500;
  font-size: 0.98rem; color: rgba(36,48,67,0.72); margin: 0;
}

/* ---------- contact ---------- */
.contact {
  display: flex; flex-direction: column; align-items: center; gap: 1.6rem;
  width: 100%; max-width: 560px;
}
.contact-links {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 0.9rem;
}
.contact-link {
  display: inline-flex; align-items: center; gap: 0.65rem;
  font-size: 0.92rem; font-weight: 500; letter-spacing: 0.2px;
  text-decoration: none; color: var(--navy);
  border: 1px solid rgba(12,35,78,0.2); background: rgba(255,255,255,0.55);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  padding: 0.6rem 1.15rem 0.6rem 0.7rem; border-radius: 999px;
  transition: border-color 0.25s ease, color 0.25s ease, transform 0.2s ease;
}
.contact-link:hover { transform: translateY(-1px); }
.email-link:hover { border-color: var(--teal); color: var(--teal); }
.orcid-link:hover { border-color: #a6ce39; color: var(--teal); }
.contact-icon, .orcid-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  color: #fff; font-size: 0.78rem; line-height: 1;
}
.contact-icon { background: var(--teal); font-size: 0.82rem; }
.orcid-icon { background: #a6ce39; font-weight: 700; font-style: italic; }

/* LinkedIn embed */
.linkedin {
  display: flex; flex-direction: column; align-items: center; gap: 1.2rem;
  width: 100%; max-width: 560px;
}
.linkedin-link {
  font-size: 0.82rem; font-weight: 600; letter-spacing: 1.5px;
  text-transform: uppercase; text-decoration: none;
  color: #fff; background: var(--teal);
  padding: 0.7rem 1.4rem; border-radius: 999px;
  transition: background 0.25s ease, transform 0.2s ease;
}
.linkedin-link:hover { background: var(--navy); transform: translateY(-1px); }

/* arrows */
.arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 52px; height: 52px; border-radius: 50%;
  border: 1px solid rgba(12,35,78,0.25);
  background: rgba(255,255,255,0.55);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  color: var(--navy); font-size: 1.4rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; z-index: 3; user-select: none;
  transition: background 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
}
.arrow:hover { background: #fff; color: var(--teal); }
.arrow.prev { left: clamp(12px, 3vw, 40px); }
.arrow.next { right: clamp(12px, 3vw, 40px); }
.arrow:disabled, .arrow[aria-disabled="true"] { opacity: 0.25; cursor: default; pointer-events: none; }

/* ---------- nav ---------- */
.nav {
  flex: none; width: 100%;
  display: flex; justify-content: center; flex-wrap: wrap; gap: 2.4rem;
  padding: 1.5rem 24px 1rem;
  border-top: 1px solid rgba(12,35,78,0.12);
}
.nav a {
  font-size: 0.8rem; font-weight: 500; letter-spacing: 1.8px;
  text-transform: uppercase; text-decoration: none; color: var(--navy);
  position: relative; padding-bottom: 5px; cursor: pointer;
  transition: color 0.25s ease;
}
.nav a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 0; height: 1.5px; background: var(--teal); transition: width 0.28s ease;
}
.nav a:hover { color: var(--teal); }
.nav a:hover::after { width: 100%; }
.nav a.active { color: var(--teal); }
.nav a.active::after { width: 100%; }

/* ---------- footer ---------- */
.footer {
  flex: none; width: 100%;
  display: flex; justify-content: center; align-items: center; gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0 24px 1.4rem;
  font-size: 0.72rem; letter-spacing: 0.6px;
  color: rgba(36, 48, 67, 0.6);
}
.footer .dot { color: rgba(36, 48, 67, 0.4); }
.footer a {
  color: var(--teal); text-decoration: none;
  border-bottom: 1px solid rgba(10, 93, 80, 0.35);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.footer a:hover { color: var(--navy); border-color: var(--navy); }

/* shorter desktop / laptop screens: compact the masthead and nav so the
   carousel keeps usable height (content also scrolls if it still overflows). */
@media (min-width: 601px) and (max-height: 740px) {
  .masthead { padding: 2.6vh 24px 0.9rem; }
  .kicker { font-size: 0.84rem; margin: 0 0 0.55rem; }
  .credential { margin: 0.55rem 0 0.3rem; }
  .affiliation { font-size: 1.12rem; }
  .nav { padding: 1rem 24px 0.7rem; }
  .footer { padding: 0 24px 1rem; }
  .slide h2 { margin: 0 0 1.4rem; }
}

@media (max-width: 600px) {
  .arrow { display: none; }          /* swipe instead */

  /* fixed app shell — header & nav stay pinned, only the active slide scrolls.
     no page scroll means horizontal swipes are never eaten by vertical panning,
     and the fixed cloud field can't jump when the mobile URL bar shows/hides. */
  html, body { height: 100%; overflow: hidden; }
  body { touch-action: pan-y; }
  .page { height: 100dvh; }

  /* flat one-slide view; the carousel is the only scrolling region */
  .carousel { flex: 1; min-height: 0; position: relative; overflow: hidden; perspective: none; }
  .track { position: static; transform: none !important; transform-style: flat; height: auto; }
  .slide {
    position: absolute; inset: 0;
    transform: none; opacity: 1 !important;   /* inline transform drives the drag; render() clears stale 3D */
    transition: none;
    justify-content: safe center;        /* centre when it fits, scroll from top when it doesn't */
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 3vh 7vw 4vh;
  }
  .slide.is-hidden { display: none; }

  /* fluid masthead — every value scales with the screen so it stays compact
     on small / short phones and only grows on roomier ones. vh-based vertical
     rhythm keeps the header from eating the screen on short devices. */
  .masthead { padding: clamp(0.65rem, 2.2vh, 1.4rem) 16px clamp(0.5rem, 1.5vh, 1rem); }
  .kicker {
    font-size: clamp(0.55rem, 2.7vw, 0.7rem);
    letter-spacing: clamp(1.4px, 0.7vw, 2.5px);
    margin: 0 0 clamp(0.28rem, 1.1vh, 0.55rem);
  }
  .name { font-size: clamp(1.6rem, 8.5vw, 2.6rem); }
  .credential {
    font-size: clamp(0.55rem, 2.5vw, 0.68rem);
    letter-spacing: clamp(1px, 0.5vw, 1.8px);
    margin: clamp(0.32rem, 1.3vh, 0.6rem) 0 0.25rem;
  }
  .affiliation { font-size: clamp(0.84rem, 3.4vw, 1.05rem); line-height: 1.32; }

  /* carousel content scales fluidly and stays comfortable to read */
  .slide h2 {
    font-size: clamp(0.8rem, 3.6vw, 0.95rem);
    gap: clamp(7px, 2.2vw, 11px);
    letter-spacing: clamp(2px, 1vw, 3.2px);
    margin: 0 0 clamp(0.9rem, 3vh, 1.4rem);
  }
  /* compact the monogram + dash so long headings never overflow narrow phones */
  .slide h2::before, .slide h2::after { width: 2.7em; }
  .slide h2::before { background-size: 1.5em 1.5em, 1em 1.3px; }
  .slide h2::after  { background-size: 1.5em 1.5em, 1em 1.3px; }
  .slide p.body { font-size: clamp(0.95rem, 3.8vw, 1.06rem); line-height: 1.75; }
  .slide .placeholder { font-size: clamp(1.08rem, 4.6vw, 1.3rem); }

  /* publications flow with the page on phones — no inner scroll, no edge mask */
  .pubs {
    max-height: none; overflow: visible; padding: 0;
    -webkit-mask-image: none; mask-image: none;
  }
  .pub { padding-left: 2rem; }
  .pub-title { font-size: 1.1rem; }
  .pub-authors { font-size: 0.8rem; }
  .pub-venue { font-size: 0.95rem; }
  .pub-link { font-size: 0.72rem; }

  /* resume flows with the page; education stacks date over details */
  .resume {
    max-height: none; overflow: visible; padding: 0;
    -webkit-mask-image: none; mask-image: none;
  }
  .edu-item { grid-template-columns: 1fr; gap: 0.4rem 0; }
  .edu-dates { padding-top: 0; }
  .edu-degree { font-size: 1.1rem; }

  /* pinned bottom navigation bar — frosted, and fluidly scaled so the seven
     links stay tidy from the smallest phones up to the largest. */
  .nav {
    gap: clamp(0.4rem, 1.6vw, 0.7rem) clamp(0.8rem, 3.4vw, 1.3rem);
    padding: clamp(0.55rem, 1.6vh, 0.9rem) 12px clamp(0.38rem, 1vh, 0.6rem);
    background: rgba(255,255,255,0.62);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  }
  .nav a { font-size: clamp(0.63rem, 2.9vw, 0.74rem); letter-spacing: clamp(0.8px, 0.5vw, 1.3px); }
  .footer {
    font-size: clamp(0.58rem, 2.5vw, 0.66rem);
    padding: clamp(0.35rem, 0.9vh, 0.5rem) 14px max(0.6rem, env(safe-area-inset-bottom));
    background: rgba(255,255,255,0.62);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  }
}
