/* ============================================================
   Restrained Bauhaus — an academic homepage
   ------------------------------------------------------------
   Principles this file commits to:
     · One accent colour. Primaries appear as marks, never as fills.
     · Rules and grids do the dividing. No shadows, no gradients.
     · Type carries the hierarchy: three sizes, two weights, one mono.
     · Nothing is rounded. Nothing is centred that could be flush left.
   ============================================================ */

/* ---------- 1. Tokens ------------------------------------- */

:root {
  /* Ground & ink */
  --ground:      #FFFFFF;
  --ground-2:    #F5F5F5;
  --ground-3:    #EBEBEB;
  --ink:         #14110F;
  --ink-2:       #55504A;
  --ink-3:       #8B857C;
  --rule:        #D9D5CA;
  --rule-strong: #14110F;

  /* The single accent. A deep petrol — same hue as the circle mark below,
     shaded darker here so white text stays readable on top of it. */
  --accent:      #1D625A;
  --accent-ink:  #FFFFFF;

  /* Mark colours — used only for the circle/square/triangle primitives. */
  --mark-petrol: #4C978D;
  --yellow:      #E3A81B;
  --mark-grey:   #47443E;

  /* Used only for the summary/bio/interests text — see .text-ultramarine. */
  --ultramarine:     #120A8F;
  --ultramarine-ink: #FFFFFF;

  --selection:   #1D625A;

  /* Type */
  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body:    "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Measure & rhythm */
  --wrap:      1280px;
  --measure:   68ch;
  --gutter:    clamp(1.25rem, 4vw, 4rem);
  --section-y: clamp(4rem, 9vw, 8.5rem);
  --header-h:  4rem;

  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* Dark: system preference, unless the user explicitly chose light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:      #100F0D;
    --ground-2:    #1A1815;
    --ground-3:    #26231F;
    --ink:         #F4F1EA;
    --ink-2:       #A9A399;
    --ink-3:       #736D64;
    --rule:        #2E2A25;
    --rule-strong: #F4F1EA;
    --accent:      #6FC0B6;
    --accent-ink:  #100F0D;
    --mark-petrol: #6FC0B6;
    --yellow:      #F0BE45;
    --mark-grey:   #948E82;
    --ultramarine:     #8B93F0;
    --ultramarine-ink: #100F0D;
    --selection:   #6FC0B6;
  }
}

/* Dark: explicit choice wins in both directions. */
:root[data-theme="dark"] {
  --ground:      #100F0D;
  --ground-2:    #1A1815;
  --ground-3:    #26231F;
  --ink:         #F4F1EA;
  --ink-2:       #A9A399;
  --ink-3:       #736D64;
  --rule:        #2E2A25;
  --rule-strong: #F4F1EA;
  --accent:      #6FC0B6;
  --accent-ink:  #100F0D;
  --mark-petrol: #6FC0B6;
  --yellow:      #F0BE45;
  --mark-grey:   #948E82;
  --ultramarine:     #8B93F0;
  --ultramarine-ink: #100F0D;
  --selection:   #6FC0B6;
}

/* ---------- 2. Reset & base ------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1, "liga" 1;
  overflow-x: hidden;
}

::selection { background: var(--selection); color: #fff; }

img, svg, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration: none; }

ul, ol { margin: 0 0 1.15em; padding-left: 1.25em; }
li { margin-bottom: 0.35em; }

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.5rem 0;
}

code, pre, kbd { font-family: var(--font-mono); font-size: 0.875em; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

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

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: 0; left: 0; z-index: 200;
  transform: translateY(-110%);
  background: var(--accent); color: var(--accent-ink);
  padding: 0.75rem 1.25rem;
  font-family: var(--font-mono); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.12em;
  transition: transform 0.15s var(--ease);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- 3. Layout primitives -------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-y);
  border-top: 1px solid var(--rule);
}
.section--flush { border-top: 0; }

/* Asymmetric editorial split: narrow label column, wide content column. */
.split {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 60rem) {
  .split { grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); }
  .split--even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Sticky section label — stays with you as the column scrolls. */
@media (min-width: 60rem) {
  .split__aside {
    position: sticky;
    top: calc(var(--header-h) + 2.5rem);
  }
}

.portrait {
  display: block;
  width: 100%;
  max-width: 12rem;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--rule);
  margin-bottom: 1.75rem;
}

/* ---------- 4. Type utilities ----------------------------- */

.label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-3);
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 0 0 1rem;
}
.label::before {
  content: "";
  width: 0.5rem; height: 0.5rem;
  flex: 0 0 auto;
  background: var(--accent);
  transform: translateY(-0.1em);
}
.label--plain::before { display: none; }

.label__num { color: var(--accent); font-weight: 600; }

.mono {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}

.display {
  font-size: clamp(2.75rem, 9.5vw, 7rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.035em;
  text-transform: uppercase;
}

.h-lg { font-size: clamp(1.9rem, 4.2vw, 3rem); letter-spacing: -0.028em; }
.h-md { font-size: clamp(1.4rem, 2.4vw, 1.9rem); letter-spacing: -0.02em; }
.h-sm { font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; }

.lede {
  font-size: clamp(1.125rem, 1.9vw, 1.375rem);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 40ch;
  text-wrap: pretty;
}

.muted { color: var(--ink-2); }
.faint { color: var(--ink-3); }

/* Applied to the specific renderings of site.summary / site.bio /
   site.interests — not a general-purpose utility, so it's not used
   anywhere the same class isn't also doing its normal job. */
.text-ultramarine { color: var(--ultramarine); }

/* Inline text link: rule sits below the baseline, thickens on hover. */
.link {
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  padding-bottom: 1px;
  transition: background-size 0.2s var(--ease), color 0.2s var(--ease);
}
.link:hover { background-size: 100% 2px; color: var(--accent); }

/* ---------- 5. Header ------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  background: var(--ground); /* fallback where color-mix is unsupported */
  background: color-mix(in srgb, var(--ground) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(12px);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--rule);
}

.header__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  white-space: nowrap;
}
.brand__mark {
  width: 1rem; height: 1rem;
  background: var(--accent);
  flex: 0 0 auto;
  transition: border-radius 0.35s var(--ease), transform 0.35s var(--ease);
}
.brand:hover .brand__mark { border-radius: 50%; transform: rotate(90deg); }

.nav { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2rem); }

.nav__link {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-2);
  padding-block: 0.35rem;
  position: relative;
  transition: color 0.18s var(--ease);
}
.nav__link:hover { color: var(--ink); }
.nav__link::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.22s var(--ease);
}
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.header__tools { display: flex; align-items: center; gap: 0.5rem; }

.icon-btn {
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  transition: border-color 0.18s var(--ease), color 0.18s var(--ease),
              background-color 0.18s var(--ease);
}
.icon-btn:hover {
  border-color: var(--rule-strong);
  color: var(--ink);
}
.icon-btn svg { width: 0.9375rem; height: 0.9375rem; }

/* Theme toggle: a half-filled circle. No sun, no moon. */
.theme-toggle .theme-toggle__half { transition: transform 0.4s var(--ease); transform-origin: center; }
:root[data-theme="dark"] .theme-toggle .theme-toggle__half { transform: rotate(180deg); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .theme-toggle__half { transform: rotate(180deg); }
}

/* Mobile nav */
.nav-toggle { display: none; }

@media (max-width: 52rem) {
  .nav-toggle { display: grid; }
  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--ground);
    border-bottom: 1px solid var(--rule);
    padding: 0.5rem var(--gutter) 1.5rem;
    transform: translateY(-100%);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
  }
  .nav[data-open="true"] { transform: translateY(0); opacity: 1; pointer-events: auto; }
  .nav__link {
    font-size: 1rem;
    padding-block: 0.9rem;
    border-bottom: 1px solid var(--rule);
    letter-spacing: 0.06em;
  }
  .nav__link::after { display: none; }
  .nav__link[aria-current="page"] { color: var(--accent); }
}

/* ---------- 6. Hero --------------------------------------- */

.hero {
  padding-block: clamp(3.5rem, 9vw, 7.5rem) clamp(3rem, 7vw, 6rem);
  position: relative;
}

.hero__grid {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: 1fr;
  align-items: end;
}
@media (min-width: 60rem) {
  .hero__grid { grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); }
}

.hero__name {
  font-size: clamp(2rem, 6vw, 4rem);
  font-weight: 800;
  line-height: 0.88;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  margin-bottom: 1.75rem;
}

.hero__role {
  font-family: var(--font-mono);
  font-size: clamp(0.8125rem, 1.3vw, 0.9375rem);
  letter-spacing: 0.06em;
  color: var(--ink-2);
  margin-bottom: 0.4rem;
}
.hero__role strong { color: var(--ink); font-weight: 500; }

.hero__affil { color: var(--ink-2); max-width: 34ch; }

.hero__status {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.75rem;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-2);
}
.hero__status::before {
  content: "";
  width: 0.4375rem; height: 0.4375rem;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.82); }
}

/* The one place the three primitives appear together. */
.primitives {
  display: flex;
  gap: 0.75rem;
  align-items: flex-end;
  margin-bottom: 2rem;
  /* Contains the square's mix-blend-mode to these three shapes only —
     without it, the blend would also mix against the page background,
     which is near-black in dark mode and would sink the square's own
     colour outside the overlap. */
  isolation: isolate;
}
.primitives > * { width: 1.75rem; height: 1.75rem; flex: 0 0 auto; }
.primitives__circle   { border-radius: 50%; background: var(--mark-petrol); }
.primitives__square   {
  background: var(--yellow);
  /* Pulls the square left by the flex gap plus half its own width, so it
     enters the circle from the right edge and the two colours mix where
     they overlap rather than one flatly occluding the other. */
  margin-left: -1.625rem;
  mix-blend-mode: multiply;
}
.primitives__triangle {
  width: 0; height: 0;
  border-left: 0.875rem solid transparent;
  border-right: 0.875rem solid transparent;
  border-bottom: 1.55rem solid var(--mark-grey);
  background: none;
}

.hero__meta {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  grid-template-columns: 1fr;
}
@media (min-width: 40rem) { .hero__meta { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68rem) { .hero__meta { grid-template-columns: repeat(4, 1fr); } }

.hero__meta-cell {
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 40rem) {
  .hero__meta-cell { padding: 1.5rem 1.5rem 1.5rem 0; border-bottom: 0; border-right: 1px solid var(--rule); }
  /* Leave the first cell flush left with the rest of the hero; give every
     cell after a divider bar some breathing room before its own text. */
  .hero__meta-cell:not(:first-child) { padding-left: 1.5rem; }
  .hero__meta-cell:last-child { border-right: 0; }
}
.hero__meta-cell dt {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-3);
  margin-bottom: 0.4rem;
}
.hero__meta-cell dd { margin: 0; font-size: 0.9375rem; line-height: 1.4; }

/* Three random photos shown side by side, refreshing together on a timer.
   Square = pause, triangle = play — the same shape vocabulary as the
   primitives mark, not literal icons. */
.slideshow {
  margin-top: clamp(2rem, 4vw, 3rem);
  border: 1px solid var(--rule);
}

.slideshow__frame {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--rule);
}

.slideshow__img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--ground-2);
  opacity: 1;
  transition: opacity 0.6s var(--ease);
}
.slideshow__img.is-fading { opacity: 0; }

.slideshow__controls {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 0.75rem;
  background: var(--ultramarine);
}

.slideshow__pause {
  width: 1.75rem;
  height: 1.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--ultramarine-ink);
  color: var(--ultramarine-ink);
  opacity: 0.75;
  flex: 0 0 auto;
  transition: opacity 0.18s var(--ease);
}
.slideshow__pause:hover { opacity: 1; }
.slideshow__pause-icon { width: 0.5rem; height: 0.5rem; background: currentColor; }
.slideshow__pause[aria-pressed="true"] .slideshow__pause-icon {
  width: 0; height: 0;
  background: none;
  border-top: 0.4rem solid transparent;
  border-bottom: 0.4rem solid transparent;
  border-left: 0.6rem solid currentColor;
}

/* ---------- 7. Buttons ------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.25rem;
  border: 1px solid var(--rule-strong);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: transparent;
  color: var(--ink);
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease),
              transform 0.18s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--ground); }
.btn:active { transform: translateY(1px); }

.btn--accent { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn--accent:hover { background: var(--ink); border-color: var(--ink); color: var(--ground); }

.btn__arrow { transition: transform 0.22s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(3px); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }

/* ---------- 8. Interests / tag grid ----------------------- */

.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.tag {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  white-space: nowrap;
}
.tag--solid { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.tag--accent { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* Numbered interest list — the grid made visible. */
.interests {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rule);
}
.interests li {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: 1rem;
  align-items: baseline;
  padding: 1rem 0;
  border-bottom: 1px solid var(--rule);
  margin: 0;
  font-size: 1.0625rem;
  transition: padding-left 0.22s var(--ease);
}
.interests li:hover { padding-left: 0.5rem; }
.interests li::before {
  content: counter(interest, decimal-leading-zero);
  counter-increment: interest;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  color: var(--accent);
}
.interests { counter-reset: interest; }

/* ---------- 9. Publications ------------------------------- */

.pub-year {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin: 3.5rem 0 0;
  padding-top: 1rem;
}
.pub-year:first-child { margin-top: 0; }
.pub-year__num {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--ink);
}
.pub-year__rule { flex: 1; height: 1px; background: var(--rule); }
.pub-year__count {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-3);
}

.pub {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--rule);
  position: relative;
}
@media (min-width: 52rem) {
  .pub { grid-template-columns: 7rem 1fr; gap: 0 2rem; }
}

.pub__badge {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  padding-top: 0.35rem;
}
.pub__badge span {
  display: inline-block;
  border-left: 2px solid var(--accent);
  padding-left: 0.5rem;
}

.pub__body { min-width: 0; }

.pub__title {
  font-size: clamp(1.0625rem, 1.7vw, 1.3125rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin-bottom: 0.5rem;
  text-wrap: pretty;
}

.pub__authors { font-size: 0.9375rem; color: var(--ink-2); margin-bottom: 0.35rem; }
.pub__authors strong { color: var(--ink); font-weight: 600; }

.pub__venue {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--ink-3);
  letter-spacing: 0.02em;
}
.pub__venue em { font-style: normal; color: var(--ink-2); }

.pub__award {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  border: 1px solid currentColor;
  padding: 0.25rem 0.5rem;
}

.pub__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
  margin-top: 1rem;
}

.pub-link {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  transition: border-color 0.18s var(--ease), color 0.18s var(--ease),
              background-color 0.18s var(--ease);
}
.pub-link:hover, .pub-link[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}

/* Collapsible abstract / bibtex */
.pub__drawer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s var(--ease);
}
.pub__drawer[data-open="true"] { grid-template-rows: 1fr; }
.pub__drawer > div { overflow: hidden; }
.pub__drawer-inner {
  margin-top: 1rem;
  padding: 1.1rem 1.25rem;
  background: var(--ground-2);
  border-left: 2px solid var(--accent);
  font-size: 0.9375rem;
  color: var(--ink-2);
  line-height: 1.6;
}
.pub__drawer-inner pre {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--ink-2);
}

.copy-btn {
  margin-top: 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.copy-btn:hover { color: var(--accent); border-color: var(--accent); }

/* Filter bar */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}
.filter {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  transition: all 0.18s var(--ease);
}
.filter:hover { border-color: var(--rule-strong); color: var(--ink); }
.filter[aria-pressed="true"] {
  background: var(--ultramarine); border-color: var(--ultramarine); color: var(--ultramarine-ink);
}

/* ---------- 10. Editorial rows (blog, talks) --------------- */

.rows { border-top: 1px solid var(--rule-strong); }

.row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.35rem 2rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
  transition: padding-left 0.25s var(--ease);
  position: relative;
}
@media (min-width: 52rem) {
  .row { grid-template-columns: 7.5rem 1fr auto; padding: 1.65rem 0; }
}
.row:hover { padding-left: 0.75rem; }

.row__date {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-3);
}
.row__title {
  font-size: clamp(1.0625rem, 1.9vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.25;
  transition: color 0.18s var(--ease);
  text-wrap: pretty;
}
.row:hover .row__title { color: var(--accent); }
.row__excerpt {
  grid-column: 1 / -1;
  color: var(--ink-2);
  font-size: 0.9375rem;
  max-width: 62ch;
  margin-top: 0.35rem;
}
@media (min-width: 52rem) { .row__excerpt { grid-column: 2 / 3; } }

.row__aside {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  white-space: nowrap;
}

.row__arrow {
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
  color: var(--accent);
}
.row:hover .row__arrow { opacity: 1; transform: translateX(0); }

/* Whole-row click target without nesting interactive elements. */
.row__link::after { content: ""; position: absolute; inset: 0; }

/* ---------- 11. Cards (teaching) -------------------------- */

.cards {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  grid-template-columns: 1fr;
}
@media (min-width: 46rem) { .cards--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .cards--3 { grid-template-columns: repeat(3, 1fr); } }

.card {
  background: var(--ground);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transition: background-color 0.2s var(--ease);
}
.card:hover {
  background: var(--ground-2); /* fallback where color-mix is unsupported */
  background: color-mix(in srgb, var(--ultramarine) 10%, var(--ground));
}

.card__code {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
}
.card__title { font-size: 1.1875rem; font-weight: 600; letter-spacing: -0.015em; line-height: 1.25; }
.card__meta {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.card__body { color: var(--ink-2); font-size: 0.9375rem; flex: 1; }
.card__links { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; padding-top: 0.5rem; }

/* ---------- 12. Timeline (CV) ----------------------------- */

.timeline-group + .timeline-group { margin-top: 2.5rem; }

.timeline { border-top: 1px solid var(--rule); }

.timeline__item {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.3rem 2rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 46rem) {
  .timeline__item { grid-template-columns: 9rem 1fr; }
}

.timeline__period {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  padding-top: 0.2rem;
}
.timeline__title { font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.01em; }
.timeline__where { color: var(--accent); font-size: 0.9375rem; margin-top: 0.1rem; }

.timeline__venues {
  list-style: none;
  margin: 0.3rem 0 0;
  padding: 0;
}
.timeline__venues li {
  color: var(--accent);
  font-size: 0.9375rem;
  line-height: 1.6;
}
.timeline__detail { color: var(--ink-2); font-size: 0.9375rem; margin-top: 0.4rem; }
.timeline__detail p { margin-bottom: 0.5em; }

/* ---------- 13. Research threads carousel ------------------ */

.threads { margin: 2rem 0 0; }

/* Horizontal scroll-snap strip. Works with zero JS — touch, trackpad and
   click-drag scrolling are all native; the arrow buttons below are a
   progressive enhancement that scrolls by exactly one card. */
.threads__track {
  display: flex;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
}
.threads__track:focus-visible { outline-offset: -2px; }

.thread-card {
  flex: 0 0 86%;
  scroll-snap-align: start;
  background: var(--ground);
  padding: clamp(1.5rem, 4vw, 2.25rem);
  box-sizing: border-box;
  border-top: 6px solid var(--mark-petrol);
}
@media (min-width: 40rem) { .thread-card { flex-basis: 62%; } }
@media (min-width: 60rem) { .thread-card { flex-basis: 40%; } }

/* Cycle the same three mark colours used for the hero primitives, so the
   carousels read as an extension of the existing palette rather than a
   new one. */
.thread-card:nth-child(3n+2) { border-top-color: var(--yellow); }
.thread-card:nth-child(3n+3) { border-top-color: var(--mark-grey); }

.thread-card__num {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

.thread-card__title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.2;
  margin-bottom: 1rem;
}

.thread-card p:last-child {
  color: var(--ink-2);
  font-size: 0.9375rem;
  line-height: 1.6;
  margin: 0;
}

/* News cards only: the cycling colour becomes the card's fill instead of
   just a border band. Text colour is set explicitly per card rather than
   inherited, since petrol and yellow stay light/bright in both themes
   (so their text has to stay dark in both themes too, unlike the rest of
   the page) while the grey card flips dark/light the same way --accent
   does, so it can reuse --accent-ink. */
.threads--news .thread-card { border-top: 0; }
.threads--news .thread-card:nth-child(3n+1) { background: var(--mark-petrol); }
.threads--news .thread-card:nth-child(3n+2) { background: var(--yellow); }
.threads--news .thread-card:nth-child(3n+3) { background: var(--mark-grey); }

.threads--news .thread-card:nth-child(3n+1) .thread-card__num,
.threads--news .thread-card:nth-child(3n+1) .thread-card__title,
.threads--news .thread-card:nth-child(3n+1) p:last-child,
.threads--news .thread-card:nth-child(3n+2) .thread-card__num,
.threads--news .thread-card:nth-child(3n+2) .thread-card__title,
.threads--news .thread-card:nth-child(3n+2) p:last-child {
  color: #14110F;
}

.threads--news .thread-card:nth-child(3n+3) .thread-card__num,
.threads--news .thread-card:nth-child(3n+3) .thread-card__title,
.threads--news .thread-card:nth-child(3n+3) p:last-child {
  color: var(--accent-ink);
}

.threads__controls { display: flex; gap: 0.5rem; margin-top: 1rem; }

.threads__arrow {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule);
  color: var(--ink-2);
  font-family: var(--font-mono);
  transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.threads__arrow:hover { border-color: var(--rule-strong); color: var(--ink); }

/* ---------- 14. Article (blog post) ----------------------- */

.progress {
  position: fixed; top: 0; left: 0; z-index: 150;
  height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: left;
  background: var(--accent);
}

.article-head {
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(2rem, 4vw, 3rem);
  border-bottom: 1px solid var(--rule-strong);
}
.article-head__title {
  font-size: clamp(2rem, 5.5vw, 3.75rem);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.035em;
  max-width: 20ch;
  margin-bottom: 1.5rem;
}
.article-head__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
}

.prose {
  max-width: var(--measure);
  padding-block: clamp(2.5rem, 5vw, 4rem);
  font-size: 1.0625rem;
  line-height: 1.72;
}
.prose > * + * { margin-top: 1.3em; }

.prose h2 {
  font-size: clamp(1.375rem, 2.6vw, 1.75rem);
  margin-top: 2.75em;
  margin-bottom: 0.1em;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  letter-spacing: -0.022em;
}
.prose h3 {
  font-size: 1.1875rem;
  margin-top: 2.25em;
  margin-bottom: 0.1em;
  letter-spacing: -0.015em;
}
.prose h2 + *, .prose h3 + * { margin-top: 0.65em; }

.prose a {
  color: var(--accent);
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: background-size 0.2s var(--ease);
}
.prose a:hover { background-size: 100% 2px; }

.prose blockquote {
  margin: 2em 0;
  padding: 0.25rem 0 0.25rem 1.5rem;
  border-left: 2px solid var(--accent);
  color: var(--ink-2);
  font-size: 1.125rem;
  line-height: 1.6;
}
.prose blockquote.text-ultramarine { color: var(--ultramarine); }
.prose blockquote p:last-child { margin-bottom: 0; }

.prose ul, .prose ol { padding-left: 1.35em; }
.prose li::marker { color: var(--accent); }
.prose li + li { margin-top: 0.4em; }

.prose img { margin-block: 2em; border: 1px solid var(--rule); }

.prose figure { margin: 2.5em 0; }
.prose figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  margin-top: 0.75rem;
}

.prose code {
  background: var(--ground-2);
  border: 1px solid var(--rule);
  padding: 0.1em 0.35em;
  font-size: 0.85em;
}
.prose pre {
  background: var(--ground-2);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--accent);
  padding: 1.1rem 1.25rem;
  overflow-x: auto;
  font-size: 0.8125rem;
  line-height: 1.6;
  margin-block: 2em;
}
.prose pre code { background: none; border: 0; padding: 0; font-size: inherit; }

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
  margin-block: 2em;
}
.prose th, .prose td {
  text-align: left;
  padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.prose th {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  border-bottom-color: var(--rule-strong);
}

/* Wide content must scroll inside itself, never the page. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.footnotes {
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
  color: var(--ink-2);
}

/* Post navigation */
.post-nav {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  grid-template-columns: 1fr;
}
@media (min-width: 46rem) { .post-nav { grid-template-columns: 1fr 1fr; } }
.post-nav__item {
  background: var(--ground);
  padding: 1.75rem clamp(1.25rem, 3vw, 2rem);
  transition: background-color 0.2s var(--ease);
}
.post-nav__item:hover { background: var(--ground-2); }
.post-nav__item:hover .post-nav__title { color: var(--accent); }
.post-nav__dir {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  margin-bottom: 0.5rem;
}
.post-nav__title { font-weight: 600; letter-spacing: -0.012em; line-height: 1.3; transition: color 0.18s var(--ease); }
.post-nav__item--next { text-align: right; }

/* ---------- 15. Contact & footer -------------------------- */

.contact__email {
  display: inline-block;
  font-size: clamp(1.25rem, 3vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
  word-break: break-word;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 3px;
  transition: background-size 0.35s var(--ease), color 0.25s var(--ease);
}
.contact__email:hover { background-size: 100% 3px; color: var(--accent); }

.footer {
  border-top: 1px solid var(--rule-strong);
  padding-block: 3rem 2.5rem;
}
.footer__grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 46rem) {
  .footer__grid { grid-template-columns: 1fr auto; align-items: end; }
}
.footer__links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
.footer__link {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-2);
  transition: color 0.18s var(--ease);
}
.footer__link:hover { color: var(--accent); }
.footer__colophon {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  line-height: 1.8;
}

/* ---------- 16. Contact form ------------------------------- */

.contact-form {
  display: grid;
  gap: 1.5rem;
  max-width: 34rem;
}

.field { display: grid; gap: 0.5rem; }

.field label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
}

.field input,
.field textarea {
  font: inherit;
  font-size: 0.9375rem;
  padding: 0.75rem 0.9rem;
  background: var(--ground);
  border: 1px solid var(--rule);
  color: var(--ink);
  transition: border-color 0.18s var(--ease);
}
.field input:focus,
.field textarea:focus { border-color: var(--rule-strong); }
.field textarea { resize: vertical; min-height: 8rem; line-height: 1.5; }

.contact-form__note {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--ink-3);
  margin-top: -0.5rem;
}

.contact-form__alt {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  color: var(--ink-2);
}

/* ---------- 17. 404 --------------------------------------- */

.notfound {
  min-height: 62vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: 4rem;
}
.notfound__code {
  font-size: clamp(5rem, 22vw, 14rem);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: -0.05em;
  color: var(--accent);
  margin-bottom: 1.5rem;
}

/* ---------- 18. Scroll reveal ----------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
[data-reveal].is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; }
}

/* No JS? Show everything. */
.no-js [data-reveal] { opacity: 1; transform: none; }

/* ---------- 19. Print ------------------------------------- */

@media print {
  .header, .footer, .progress, .btn-row, .filters, .primitives, .post-nav { display: none !important; }
  body { background: #fff; color: #000; font-size: 10.5pt; }
  a { color: #000; text-decoration: underline; }
  .section { border-top: 1px solid #999; padding-block: 1.25rem; page-break-inside: avoid; }
  .pub, .timeline__item, .row { page-break-inside: avoid; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}
